# -*- coding: utf-8 -*-
import os
import re

from ppms.constants import *
from ppms.migration import SQLPacket, PacketCategory, MaxVersionDependency, VersionType, PacketDependency, PacketState


class AddObjectsForScheduler(SQLPacket):
    """Add new objects for the scheduling component"""
    done_after_success = True
    run_on_startup = True
    category = PacketCategory.CATEGORY_MANDATORY
    wi_number = 21672

    def get_dependencies(self):
        critical_path_packet = 'migration.server.S_39_5_25.WI21471_create_critical_path_di.CreateCriticalPathDI'

        return (MaxVersionDependency(version='39.5.11', version_type=VersionType.CUSTOMIZING),
                PacketDependency(packet_path=critical_path_packet, expected_state=PacketState.INSTALLED))

    def drop_triggers(self, folder):
        for filename in os.listdir(folder):
            filename_no_extension = os.path.splitext(filename)[0]

            if self.trigger_exists(trigger_name=filename_no_extension):
                self.log("Trigger '{trigger_name}' already exists, dropping".format(trigger_name=filename_no_extension))
                self.drop_trigger(trigger_name=filename_no_extension)

        return

    def drop_views(self, folder):
        for filename in os.listdir(folder):
            filename_no_extension = os.path.splitext(filename)[0]

            if self.view_exists(view_name=filename_no_extension):
                self.log("View '{view_name}' already exists, dropping".format(view_name=filename_no_extension))
                self.drop_view(view_name=filename_no_extension)

        return

    def add_sequences(self, folder, separator):
        for filename in os.listdir(folder):
            file_path = os.path.join(folder, filename)
            filename_no_extension = os.path.splitext(filename)[0]

            if self.sequence_exists(sequence_name=filename_no_extension):
                self.log('There is already a sequence with the name "{}"'.format(filename_no_extension))
                continue

            with open(file_path, 'r') as f:
                content = f.read()

            queries = [query for query in re.split(separator, content, flags=re.MULTILINE) if query.strip()]

            for query in queries:
                self.modify_and_log(query=query, log_rows=False)

        return

    def add_triggers(self, folder, separator):
        for filename in os.listdir(folder):
            file_path = os.path.join(folder, filename)

            with open(file_path, 'r') as f:
                content = f.read()

            queries = [query for query in re.split(separator, content, flags=re.MULTILINE) if query.strip()]

            for query in queries:
                self.modify_and_log(query=query, log_rows=False)

        return

    def add_views(self, folder, separator):
        for filename in os.listdir(folder):
            file_path = os.path.join(folder, filename)

            with open(file_path, 'r') as f:
                content = f.read()

            queries = [query for query in re.split(separator, content, flags=re.MULTILINE) if query.strip()]

            for query in queries:
                self.modify_and_log(query=query, log_rows=False)

        return

    def fix(self, packet_runner):
        this_folder = os.path.dirname(os.path.realpath(__file__))
        sequence_folder = os.path.join(this_folder, 'sequences')
        trigger_folder = os.path.join(this_folder, 'triggers')
        view_folder = os.path.join(this_folder, 'views')

        if self.DBMS == DBMS_ORACLE:
            dbms_folder = 'oracle'
            separator = ';/'
        elif self.DBMS == DBMS_MSSQL:
            dbms_folder = 'mssql'
            separator = 'GO'
        else:
            return self.fail('Invalid dbms: {}'.format(self.DBMS))

        dbms_specific_sequence_folder = os.path.join(sequence_folder, dbms_folder)
        dbms_specific_trigger_folder = os.path.join(trigger_folder, dbms_folder)
        dbms_specific_view_folder = os.path.join(view_folder, dbms_folder)

        self.log("Dropping existing objects")
        self.drop_triggers(dbms_specific_trigger_folder)
        self.drop_views(dbms_specific_view_folder)

        self.log("Creating new objects")
        self.add_sequences(dbms_specific_sequence_folder, separator)
        self.add_views(dbms_specific_view_folder, separator)
        self.add_triggers(dbms_specific_trigger_folder, separator)

        self.log("All objects created successfully")

        return self.success()
