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

from .config import DATABASE as db_config
from .config import MODE

from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker


def get_db_uri(db_config: dict):
    """Get a URI for connecting to a database.

    This function supports SQLite, PostgreSQL, MySQL and probably some
    other server-based RDBMS.

    :param db_config: A dict containing what is necessary for creating
    the URI.
    """
    if db_config['dialect'] == 'sqlite':
        uri_pattern = '{db[dialect]}:///{db[file]}'
    else:
        if 'port' in db_config:
            uri_pattern = ('{db[dialect]}://{db[user]}:{db[password]}'
                           '@{db[host]}:{db[port]}/{db[database]}')
        else:
            uri_pattern = ('{db[dialect]}://{db[user]}:{db[password]}'
                           '@{db[host]}/{db[database]}')
    uri = uri_pattern.format(db=db_config)
    return uri


BASE = declarative_base()


class FormAnalysis(BASE):
    """A FormAnalysis holds represents an analysis produced by Morpheus."""

    __tablename__ = 'FormAnalysis'
    id = Column(Integer, primary_key=True, autoincrement=True)
    form = Column(String(50), nullable=False, index=True)
    # LDT tags have length 9, PROIEL tags have length 12
    morphtag = Column(String(12), nullable=True)
    lemma = Column(String(50), nullable=True)
    accented = Column(String(60), nullable=True)

    # Ideally, this table would have a joined UNIQUE constraint for
    # form, morphtag, lemma and accented, but this would make
    # insertions cumbersome. It’s easier to insert everything and to
    # delete the duplicates afterwards. See the WordList object for
    # how that is done.

    def __repr__(self):
        return ('<FormAnalysis(form={f.form}, morphtag={f.morphtag}'
                ', lemma={f.lemma}, accented={f.accented})>').format(f=self)

    def __str__(self):
        return repr(self)

    def __eq__(self, other):
        return (isinstance(other, FormAnalysis)
                and ((self.form, self.morphtag, self.lemma, self.accented)
                     == (other.form, other.morphtag,
                         other.lemma, other.accented)))

    def __hash__(self):
        return hash((self.form, self.morphtag, self.lemma, self.accented))


ENGINE = create_engine(get_db_uri(db_config))
SESSION_FACTORY = sessionmaker(bind=ENGINE)
if 'run' in MODE:
    BASE.metadata.create_all(ENGINE)