# coding=utf-8
import itertools

from ppms import ppms
from ppms.constants import *
from ppms.migration import SQLPacket, PacketCategory
from ppms.module_subclasses.resource import ResourceBase


class ListIndividualModWithStartEndPeriod(SQLPacket):
    """Logs modules with period DI customizing where deleting/creation of periods doesn't work.

    Modules reported here need to be checked that their module-subclass is a subclass of ppms.module_subclasses.resource.ResourceBase.
    This packet will always fail as long as there are still modules with period DIs without the correct subclass in the system."""
    done_after_success = False
    run_on_startup = False
    category = PacketCategory.CATEGORY_HELPER
    wi_number = 1325

    def get_modules_with_period_dis(self):
        self.log_heading('Checking for modules with period DIs')
        sys_lic = ppms.uvar_get(SYS_VAR_LICENSE)
        get_mod_list = """SELECT DI000123 FROM DT405 WHERE DI000123 IN (
            SELECT DI000970 FROM DT406
            WHERE DI000969 in (
                SELECT DI000306 FROM DT411
                WHERE DI000213 = '001230' OR DI000213 = '001231'
                )
            )
        AND DI001825 = '{sys_lic}'
        """.format(**locals())

        modules = self.select_and_log(get_mod_list)

        return sorted(itertools.chain(*modules))

    def is_subclass_of_resource_module(self, module_id):
        # Imported late so the migration packet doesn't fail to import on a system without this function
        from ppms.interface import get_module_subclass

        module_subclass = get_module_subclass(module_id)
        if module_subclass is None:
            return False

        return issubclass(module_subclass, ResourceBase)

    def get_module_name_and_subclass_path(self, mod_id):
        rec = ppms.search_record(405, [mod_id], ['name', 'python_module_subclass'])
        if rec is None:
            return '', ''

        return rec.name.get_value(), rec.python_module_subclass.get_value()

    def write_report(self, modules_with_wrong_class):
        self.log_heading('Modules with incompatible subclass')

        for module in modules_with_wrong_class:
            module_name, subclass_path = self.get_module_name_and_subclass_path(module)

            if subclass_path:
                self.log('{module} "{module_name}" has subclass "{subclass_path}"'.format(**locals()))
            else:
                self.log('{module} "{module_name}" has no subclass'.format(**locals()))

    def fix(self, packet_runner):
        modules = self.get_modules_with_period_dis()

        if not modules:
            self.log('No modules with period dataitems found')
            return self.success()

        modules_with_wrong_class = []
        for module_id in modules:
            if self.is_subclass_of_resource_module(module_id):
                continue
            else:
                modules_with_wrong_class.append(module_id)

        if modules_with_wrong_class:
            self.write_report(modules_with_wrong_class)
            return self.fail('%d modules must be checked' % len(modules_with_wrong_class))

        return self.success()
