# -*- coding: utf-8 -*-

from ppms import ppms
from ppms.constants import *
from ppms.sql import sanitize_value
from ppms.migration import SQLPacket, PacketCategory, ChangeDTPPacket, PacketDependency, \
    PacketState, MaxVersionDependency, VersionType


UPDATE_QUERY = """UPDATE DT405 SET DI056952 = 'ppms.module_subclasses.base_class.Base'
WHERE (
  DI056952 IS NULL OR DI056952 = '' ) AND DI000123 NOT IN (SELECT DI000750 FROM DT433)"""

ENLARGE_COLUMN_QUERIES = {DBMS_ORACLE: ["ALTER TABLE DT411 MODIFY DI000223 VARCHAR2(100 CHAR)",
                                        "ALTER TABLE DT411_HIS MODIFY DI000223 VARCHAR2(100 CHAR)"],
                          DBMS_MSSQL: ["ALTER TABLE DT411 ALTER COLUMN DI000223 varchar(100)",
                                       "ALTER TABLE DT411_HIS ALTER COLUMN DI000223 varchar(100)"]}


def get_varchar_column_length(table, column):
    """Get the length of a varchar column"""
    dbms = ppms.db_get_dbms_name()

    if dbms == DBMS_ORACLE:
        query = """select CHAR_LENGTH from user_tab_columns
        where
          table_name = '{table}'
          and column_name = '{column}'"""

    elif dbms == DBMS_MSSQL:
        query = """select  character_maximum_length
  from information_schema.columns
 where table_name = '{table}'
 and COLUMN_NAME = '{column}'"""

    else:
        raise NotImplementedError()

    try:
        return ppms.db_select(query.format(table=sanitize_value(table),
                                           column=sanitize_value(column)))[0][0]
    except IndexError:
        return 0


class A_EnlargeDefaultValueColumn(SQLPacket):
    """Enlarge the size of DI 000223 default value to 100"""
    done_after_success = True
    run_on_startup = True
    category = PacketCategory.CATEGORY_MANDATORY
    wi_number = 16208

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

    def fix(self, packet_runner):
        current_length = get_varchar_column_length(table='DT411', column='DI000223')

        self.log('DI000223 currently has a length of %d' % current_length)

        if current_length == 20:
            self.log('Enlarging it to 20!')
            for query in ENLARGE_COLUMN_QUERIES.get(ppms.db_get_dbms_name(), []):
                self.modify_and_log(query)

            return self.success()

        elif current_length >= 100:
            self.log('Column is already large enough')

            return self.success()

        return self.fail('DI000223 does not have the expected length of 20')


class B_EnlargeDefaultValueDictionary(ChangeDTPPacket):
    """Enlarge DI000223 to use the new 100 column length"""
    done_after_success = True
    run_on_startup = True
    category = PacketCategory.CATEGORY_MANDATORY
    wi_number = 16208

    def get_dependencies(self):
        return (PacketDependency(
            packet_path='migration.server.S_39_5_18.wi16208_module_subclass.A_EnlargeDefaultValueColumn',
            expected_state=PacketState.INSTALLED), MaxVersionDependency(version='39.5.7',
                                                                        version_type=VersionType.CUSTOMIZING))

    def fix(self, packet_runner):
        record = self.get_record(dt_num=412, key_list=['000223'], di_list=['db_length', 'df_length'])

        if self.change_value(record=record, attribute='db_length', old_value=20, new_value=100) and \
                self.change_value(record=record, attribute='df_length', old_value=20, new_value=100):

            return self.success()

        else:
            return self.fail('Could not change values')


class C_AddDefaultModuleSubclass(ChangeDTPPacket):
    """Give new modules a default subclass"""
    done_after_success = True
    run_on_startup = True
    category = PacketCategory.CATEGORY_MANDATORY
    wi_number = 16208

    def get_dependencies(self):
        return (PacketDependency(
            packet_path='migration.server.S_39_5_18.wi16208_module_subclass.B_EnlargeDefaultValueDictionary',
            expected_state=PacketState.INSTALLED), MaxVersionDependency(version='39.5.7',
                                                                       version_type=VersionType.CUSTOMIZING))

    def fix(self, packet_runner):
        record = self.get_record(dt_num=411, key_list=['044020', 712322], di_list=['default_value', 'mandatory'])

        if self.change_value(record=record, attribute='mandatory', old_value=0, new_value=1) and \
                (self.verify_value(record=record, attribute='default_value', value='') or
                     self.verify_value(record=record, attribute='default_value',
                                       value='ppms.module_subclasses.base_class.Base')) and \
                        ppms.db_modify("UPDATE DT411 SET DI000223 = 'ppms.module_subclasses.base_class.Base' WHERE "
                                       "DI000306 = '044020' AND DI000307 = '712322'") == 1:
            return self.success()

        else:
            return self.fail('Could not change values')


class D_AddExplicitModuleSubclass(SQLPacket):
    """Give every module a explicit module subclass"""
    done_after_success = True
    run_on_startup = True
    category = PacketCategory.CATEGORY_MANDATORY
    wi_number = 16208

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

    def fix(self, packet_runner):
        self.modify_and_log(UPDATE_QUERY)
        return self.success()
