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

from ppms.migration import BasePacket, PacketCategory, get_all_packets, FailedPacket, PacketDependency, PacketState
from ppms.constants import *


__all__ = ['CleanupPacketData']


def packet_has_only_planta_history(packet):
    """Check if all history entries of a packet belong to PLANTA"""
    packet_record = planta.search_record(314, [packet.migrationrule], ['own_lic'])
    history_records = packet_record.get_children(315, ['own_lic'])

    if packet_has_no_history(packet):
        return True

    for history_record in history_records:
        owner_license = history_record.own_lic.get_value()

        if owner_license not in PLANTA_LICENSES:
            return False

    return True


def packet_has_no_history(packet):
    """Check if a packet has any history entries"""
    packet_record = planta.search_record(314, [packet.migrationrule], ['own_lic'])
    history_records = packet_record.get_children(315, ['own_lic'])

    return len(history_records) == 0


def packet_has_planta_license(packet):
    """Check if a packet has the owner license of PLANTA"""
    packet_record = planta.search_record(314, [packet.migrationrule], ['own_lic'])
    owner_license = packet_record.own_lic.get_value()

    return owner_license in PLANTA_LICENSES


def packet_is_from_customer_folder(packet):
    """Check if a packet resides in the customer folder"""
    pythonpath = packet.pythonpath

    return pythonpath.startswith('migration.customer.')


def delete_planta_history_records(packet):
    """Delete all history entries that belong to PLANTA"""
    packet_record = planta.search_record(314, [packet.migrationrule], ['own_lic'])
    history_records = packet_record.get_children(315, ['own_lic'])

    deleted_histories = 0

    for history_record in history_records:
        owner_license = history_record.own_lic.get_value()

        if owner_license in PLANTA_LICENSES:
            history_record.delete()

            deleted_histories += 1

    return deleted_histories


class CleanupPacketData(BasePacket):
    """A special packet that cleans up the migration packets

    Removes history data that is not relevant to the current system
    """
    category = PacketCategory.CATEGORY_HELPER
    run_on_startup = False  # This packet is run by the migration framework before the migration
    special_snowflake = True
    wi_number = 16333

    def get_dependencies(self):
        return PacketDependency(packet_path='migration.server.S_39_5_13.wi12349_add_entity.Entity',
                                expected_state=PacketState.INSTALLED)

    def delete_invalid_packets_with_planta_license(self):
        """Remove all invalid packets that are 100% PLANTA made"""
        packets = get_all_packets()

        self.log_heading('Removing invalid packets with PLANTA license')
        for packet in packets:
            if isinstance(packet, FailedPacket):
                if packet_has_planta_license(packet) and packet_has_only_planta_history(packet):
                    self.log('Deleting entry for %s' % packet.pythonpath)
                    packet.delete()

        self.log('Job complete')

    def delete_invalid_packets_that_are_not_in_customer_folder(self):
        """Remove all invalid packets that are 99% PLANTA made"""
        packets = get_all_packets()

        self.log_heading('Removing invalid packets that are not in the customer folder')
        for packet in packets:
            if isinstance(packet, FailedPacket) and not packet_is_from_customer_folder(packet=packet):
                self.log('Deleting entry for %s' % packet.pythonpath)
                packet.delete()

        self.log('Job complete')

    def delete_planta_history(self):
        """Remove all history entries that belong to PLANTA"""
        packets = get_all_packets()

        self.log_heading('Removing history data with PLANTA license')
        for packet in packets:
            deleted_histories = delete_planta_history_records(packet)

            if deleted_histories > 0:
                self.log(
                    'Deleted %d history entries in packet %s (%s)' % (deleted_histories, packet, packet.pythonpath))

        self.log('Job complete')

    def resolve_planta_packets(self):
        """Set packets that belong to PLANTA with no history to done"""
        packets = get_all_packets()

        self.log_heading('Setting PLANTA packets to done')
        for packet in packets:
            if not packet.done and \
                    packet_has_planta_license(packet) and packet_has_only_planta_history(packet) and \
                    packet.done_after_success:

                self.log('Packet %s (%s) seems safe to resolve - doing that' % (packet, packet.pythonpath))
                packet.log('CleanupPacketData deemed this packet to be solved already')
                packet.done = True
                packet.success()
                packet.save_history()

        self.log('Job complete')

    def fix(self, runner):
        packets = get_all_packets()
        self.log_heading('Analyzing and cleaning up %d packets' % (len(packets)))

        self.delete_invalid_packets_with_planta_license()
        self.delete_invalid_packets_that_are_not_in_customer_folder()
        self.delete_planta_history()
        self.resolve_planta_packets()

        self.log('Done with the cleanup')

        return self.success()