#!/usr/bin/env python3
# -*- coding: utf-8 -*-


from sqlalchemy import Column, ForeignKey
from sqlalchemy.dialects.postgresql import ENUM
import json
import logging


logger = logging.getLogger('sqlalchemy')

__all__ = ['NonNullColumn']


class NonNullColumn(Column):
    """SQLAlchemy column class with NOT NULL constraint by default

    This class inherits sqlalchemy.Column, but has a NOT NULL constraint by
    default.
    It also implements functions needed to generate the
    Database_Description_Document.
    """
    inherit_cache = True

    def __init__(self, *args, nullable=False, descr='', comment='', unique=False, **kwargs):
        """
        Note that the :param comment: is not the same as the parameter 'comment'
        of sqlalchemy.Column.
        """

        self.descr = descr
        self.doc_comment = comment
        self.priority = None

        self.sql_type = list(args).pop(0)

        if self.sql_type.__class__ == ENUM:
            self.sql_type = 'ENUM'


        try:
            if kwargs['primary_key']:
                self.priority = 'PK'
        except KeyError:
            if nullable:
                self.priority = 'N'
            else:
                self.priority = 'NN'

        if self.priority == 'PK':
            self.descr = 'Primary key'

        if unique:
            self.doc_comment = f'Must be unique. {self.doc_comment}'


        # if column is a foreign key, generate the corresponding description
        try:
            fk = list(args).pop(1)
            if fk.__class__ == ForeignKey:
                column = fk._colspec.split('.')
                self.descr = f'FK reference to {column[2]} in the {column[0]}.{column[1]} table'
        except IndexError:
            pass

        super(NonNullColumn, self).__init__(*args,
                                            **kwargs,
                                            nullable=nullable,
                                            unique=unique)

    def __repr__(self):

        infos = {
            'name': f'{self.key}',
            'sql_type': f'{self.sql_type}',
            'description': f'{self.descr}',
            'priority': f'{self.priority}',
            'comment': f'{self.doc_comment}'
        }

        return json.dumps(infos, indent=4)

    def infos(self):

        return {
            'name': f'{self.key}',
            'sql_type': f'{self.sql_type}',
            'description': f'{self.descr}',
            'priority': f'{self.priority}',
            'comment': f'{self.doc_comment}'
        }


