from enum import Enum
from .. import db
from .base import BaseModel


class Disposition(Enum):
    NEUTRAL = 'NEUTRAL'
    POSITIVE = 'POS'
    NEGATIVE = 'NEG'
    EDGE = 'EDGE'
    DESTRUCTIVE = 'DESTRUCTIVE'


class TestDatum(BaseModel):
    __tablename__ = 'test_data'

    # fields
    test_id = db.Column(db.Integer, db.ForeignKey('tests.id'), nullable=False)
    datum_id = db.Column(db.Integer, db.ForeignKey('data.id'), nullable=False)
    label = db.Column(db.String(length=80), nullable=False)
    disposition = db.Column(db.Enum(Disposition), nullable=False)

    # relationships
    test = db.relationship('Test', back_populates='data', foreign_keys=[test_id])
    datum = db.relationship('Datum', back_populates='tests', foreign_keys=[datum_id])

    @staticmethod
    def ensure_uniqueness(test_id, label):
        old_td = TestDatum.query.filter_by(test_id=test_id, label=label).first()
        if old_td is not None:
            err = (f'Each datum within a test must have a unique label, and '
                   f'there is already a datum labeled "{label}" within this test')
            raise Exception(err)

    @staticmethod
    def create(*args, **kwargs):
        if kwargs.get('test') is not None:
            kwargs['test_id'] = kwargs['test'].id
        TestDatum.ensure_uniqueness(kwargs['test_id'], kwargs['label'])
        td = TestDatum(**kwargs)
        db.session.add(td)
        db.session.commit()
