# -*- coding: utf-8 -*-
from collections import namedtuple

from ppms import ppms
from ppms.constants import *
from ppms.migration import SQLPacket, PacketCategory, MinVersionDependency, MaxVersionDependency

ChangeValue = namedtuple('ChangeValue', ('table_name', 'column_name', 'desired_precision', 'expected_precision'))

VALUES_TO_CHANGE = [ChangeValue('DT480', 'DI041705', 10, 5),
                    ChangeValue('DT480', 'DI041707', 10, 5),
                    ChangeValue('MIGRATIONHISTORY_HIS', 'TIMESTAMP', 10, None),
                    ChangeValue('DT391', 'DI040927', 22, None)]

class FixColumnPrecisions(SQLPacket):
    """Fix incorrect precision values for certain columns"""
    done_after_success = True
    run_on_startup = True
    category = PacketCategory.CATEGORY_MANDATORY
    wi_number = 17856

    def get_dependencies(self):
        return (MinVersionDependency(version='39.5.6'),
                MaxVersionDependency(version='39.5.6'))

    def convert_to_numeric(self, table_name, column_name, precision, scale):
        query = "ALTER TABLE {table_name} " \
                "ALTER COLUMN {column_name} numeric({precision}, {scale})" \
                "".format(table_name=table_name, column_name=column_name,
                                               precision=precision, scale=scale)
        self.modify_and_log(query, log_rows=False)

        return True

    def fix(self, packet_runner):
        errors = False
        dbms = ppms.db_get_dbms_name()

        for table_name, column_name, desired_precision, expected_precision in VALUES_TO_CHANGE:
            # skip this column in mssql as it already has the correct type
            if dbms == DBMS_MSSQL and column_name == 'DI040927':
                continue
            elif dbms == DBMS_MSSQL and table_name in ('MIGRATIONHISTORY_HIS', 'DT391'):
                self.log('Changing {column_name} column in table {table_name} to correct column type'.format(
                    column_name=column_name, table_name=table_name
                ))

                result = self.convert_to_numeric(table_name=table_name, column_name=column_name,
                                                 precision=desired_precision, scale=0)

            else:
                result = self.alter_precision_of_numeric_column(table_name=table_name, column_name=column_name,
                                                                expected_precision=expected_precision,
                                                                desired_precision=desired_precision)

            if not result:
                errors = True

        if errors:
            return self.fail('Not all columns could be corrected')

        return self.success()
