# -*- coding: utf-8 -*-
import itertools

from ppms import ppms
from ppms.sql import sanitize_value
from ppms.interface import Config, MtsPoolModule, get_module_subclass
from ppms.migration import SQLPacket, PacketCategory, MinVersionDependency, MaxVersionDependency, VersionType


class MigratePoolModuleConfigurations(SQLPacket):
    """Migrate the parameters of pool modules in the PLANTA Link

    Since the da_name parameter for pool modules is now split into two separate
    parameters (sending_da and receiving_da) we must migrate all old configurations
    """
    done_after_success = True
    run_on_startup = True
    category = PacketCategory.CATEGORY_MANDATORY
    wi_number = 16521

    def get_dependencies(self):
        return (MinVersionDependency(version='39.5.7', version_type=VersionType.CUSTOMIZING),
                MaxVersionDependency(version='39.5.7', version_type=VersionType.CUSTOMIZING))

    def purge_invalid_systems(self):
        self.log('Removing SYSTEM entries that do not point to a valid system')
        query = "UPDATE INTERFACE_PARAMETER SET SYSTEM = NULL WHERE SYSTEM NOT IN (SELECT UUID FROM SYSTEM)"

        self.modify_and_log(query=query)

    def get_interface_configs_with_pool(self):
        query = "SELECT UUID " \
                "FROM INTERFACE_CONFIG " \
                "WHERE POOL_MODULE IS NOT NULL "

        result = ppms.db_select(query)

        configurations = [Config(config_id) for config_id in itertools.chain(*result)]

        return configurations

    def get_da_name_value(self, config_id, pool_module):
        query = "SELECT VALUE " \
                "FROM INTERFACE_PARAMETER " \
                "WHERE CONFIG_ID = '{config_id}' " \
                "AND SOURCE = '{pool_module}' " \
                "AND NAME = 'da_name'"

        result = ppms.db_select(query.format(pool_module=pool_module,
                                             config_id=sanitize_value(config_id)))

        try:
            return result[0][0]
        except IndexError:
            return None

    def copy_da_name_into_new_parameters(self, config_id, source):
        query = """INSERT INTO
  INTERFACE_PARAMETER
   ("CONFIG_ID", "SYSTEM", "SOURCE", "CREATED_ON", "MODIFIED_ON", "RWDU", "CREATED_BY",
    "MODIFIED_BY", "OWN_LIC", "OPC", "OWNER", "GROUP", "ANY", "NAME", "VALUE", "POSITION")
SELECT
   "CONFIG_ID", "SYSTEM", "SOURCE", "CREATED_ON", "MODIFIED_ON", "RWDU", "CREATED_BY",
   "MODIFIED_BY", "OWN_LIC", "OPC", "OWNER", "GROUP", "ANY", '{new_parameter}', "VALUE", "POSITION"
FROM
  INTERFACE_PARAMETER
WHERE
  SOURCE = '{source}'
  AND CONFIG_ID = '{config_id}'
  AND NAME = 'da_name'"""

        for new_parameter in ('receiving_da', 'sending_da'):
            formatted_query = query.format(new_parameter=new_parameter, source=source,
                                           config_id=sanitize_value(config_id))

            self.modify_and_log(query=formatted_query)

    def delete_old_da_name_parameter(self, config_id, source):
        query = """DELETE
  INTERFACE_PARAMETER
WHERE
  SOURCE = '{source}'
  AND CONFIG_ID = '{config_id}'
  AND NAME = 'da_name'"""

        formatted_query = query.format(source=source, config_id=sanitize_value(config_id))

        self.modify_and_log(query=formatted_query)

    def fix(self, packet_runner):
        self.purge_invalid_systems()

        configurations = self.get_interface_configs_with_pool()

        self.log('There are %d configurations with a pool module to check' % len(configurations))
        for config in configurations:
            self.log('Examining "%s"' % config.description)

            pool_module = config.pool_module
            pool_module_subclass = get_module_subclass(mod_id=pool_module, raise_errors=True)

            if issubclass(pool_module_subclass, MtsPoolModule):
                da_name_value = self.get_da_name_value(config_id=config.config_id, pool_module=pool_module)
                if da_name_value is None:
                    self.log('No da_name parameter exists, so there is nothing to migrate')
                else:
                    self.log('Copying the da_name parameter to the 2 new parameters')
                    self.copy_da_name_into_new_parameters(config_id=config.config_id, source=pool_module)

                    self.log('Deleting the old da_name parameter')
                    self.delete_old_da_name_parameter(config_id=config.config_id, source=pool_module)

                    self.log('Successfully migrated')
            else:
                self.log('The pool module is not of a class that has to be migrated (%s)' % type(pool_module_subclass))

        return self.success()
