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

import itertools

from ppms import ppms
from ppms import ppms_cu
from ppms.constants import *
from ppms.migration import PacketCategory, MaxVersionDependency, VersionType, MinVersionDependency, \
    ChangeDTPPacket, SQLPacket, SucceedOldPacket, SinglePacketRunner, get_packet_instance_from_path


def flatten(nested_list):
    return list(itertools.chain.from_iterable(nested_list))


class FixEarnedValue(ChangeDTPPacket, SucceedOldPacket, SQLPacket):
    """Add schema objects for Earned Value Analysis

    Does nothing if the packet from S39.5.14 already ran successfully.
    """
    done_after_success = True
    run_on_startup = True
    category = PacketCategory.CATEGORY_MANDATORY
    wi_number = 17311

    __PATH = r'migration.hotfix.S_39_5_14.WI10922_fix_earned_value.FixEarnedValueSchema'
    dbms = ppms.db_get_dbms_name()

    DDL_FILENAMES = ('WI10922_DT827_CONDENSED.sql',
                     'WI10922_V_EVA_PR.sql',
                     'WI10922_V_EVA_VG.sql',
                     'WI10922_V_EVA_VGR.sql',
                     'WI10922_V_PLANTA_CUMU_DT827.sql')
    DROP_OBJECTS = ('T_RSUM',
                    'DT827_CONDENSED',
                    'V_EVA_VGR',
                    'V_EVA_VGR_B',
                    'V_EVA_JOIN_BASELINE',
                    'V_EVA_BASELINE',
                    'V_EVA_REPORTS',
                    'V_EVA_ALL_MONTHS',
                    'V_EVA_PR',
                    'V_EVA_VG',
                    'V_PLANTA_CUMU_DT827',
                    'P_RunningSum_827')
    DROP_QUERY = "SELECT 'DROP ' || object_type || ' ' || object_name FROM sys.all_objects WHERE upper(object_name) = '{object}' AND owner = user"

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

    def fix(self, runner):
        packet = get_packet_instance_from_path(self.__PATH)
        uuid = packet.migrationrule

        if uuid:
            history_record = ppms.search_record(314, [uuid], ['done'])

            if packet.dependencies_are_met and not history_record.done:
                self.log("Executing packet '{packet_path}'".format(packet_path=self.__PATH))
                sp_runner = SinglePacketRunner(uuid)
                sp_runner.run()

                return self.success()

        else:            
            if self.DBMS == DBMS_ORACLE:
                for object in self.DROP_OBJECTS:
                    for statement in flatten(ppms.db_select(self.DROP_QUERY.format(object=object))):
                        try:
                            ppms.db_modify(statement)
                        except ppms.DatabaseError as e:
                            if 'ORA-00942' not in str(e):
                                return self.fail("Exception occured when executing statement \"{statement}\": \"{exception}\"".format(statement=statement, exception=e))

            elif self.DBMS == DBMS_MSSQL:
                self.apply_rollback_ddl_file(self.sql_planta_de_dbms, 'WI10922_fix_earned_value_schema.sql', True)

            for filename in self.DDL_FILENAMES:
                self.apply_fix_ddl_file(self.sql_planta_de_dbms, filename, True)

            self.apply_fix_ddl_file(self.sql_planta_de_dbms, 'WI10922_P_RUNNINGSUM_827.sql')

        return self.success()