#!/usr/bin/python3

import re, random

from sqlalchemy.sql import func

from appl.models import SpaVerb, EngVerb, Pronoun, Exception, Translation, \
                        Ending, Tense, Person

TransRE = re.compile(r'([\w\s]+) \(.*')

TenseNames = [ 'Present', 'Preterite', ]

def special(spaverb, tense, person):
    p = Exception.query.filter_by(spa_verb=spaverb, person_id=person.id,
                                  tense_id=tense.id).first()
    if p:
        return p.conjugation

    return False

def tensename2tense(tensename):
    return Tense.query.filter_by(name=tensename).first()
    
def conjugate(spaverbinf, tensename, person):
    tense = tensename2tense(tensename)
    spaverb = getspaverb(spaverbinf)
    s = special(spaverb, tense, person)
    if s:
        return s
    e = Ending.query.filter_by(ending=spaverb.ending, tense_id=tense.id,
                               person_id=person.id).first()
    if e:
        return f'{spaverb.stem}{e.newending}'
    else:
        return 'wtf?'

def matchtranslation(spaverbinf, trans):
    trans = trans.strip()
    trans = re.sub(r'\s+', ' ', trans)
    spaverb = getspaverb(spaverbinf)
    tlats = Translation.query.filter_by(spa_verb_id=spaverb.id).all()
    for t in tlats:
        t = t.eng_verb.infinitive
        m = TransRE.match(t)
        if m:
            t = m.group(1)
        if trans == t:
            return True

    return False

def matchengtranslation(engverbinf, trans):
    trans = trans.strip()
    trans = re.sub(r'\s+', ' ', trans)
    engverb = getengverb(engverbinf)
    tlats = Translation.query.filter_by(eng_verb_id=engverb.id).all()
    for t in tlats:
        t = t.spa_verb.infinitive
        m = TransRE.match(t)
        if m:
            t = m.group(1)
        if trans == t:
            return True

    return False

def matchconjugation(spaverbinf, tensename, pronoun, trans):
    tense = tensename2tense(tensename)

    trans = trans.strip()
    trans = re.sub(r'\s+', ' ', trans)

    pron = Pronoun.query.filter_by(pronoun=pronoun).first()
    person = pron.person

    conj = conjugate(spaverbinf, tensename, person)
    return conj == trans
        
def spa_trans_str(spaverbinf):
    v = getspaverb(spaverbinf)
    return '; '.join([ t.eng_verb.infinitive for t in v.translations ])

def getspaverb(infinitive):
    return SpaVerb.query.filter_by(infinitive=infinitive).first()

def chkspaverb(infinitive):
    return getspaverb(infinitive) is not None

def getengverb(infinitive):
    return EngVerb.query.filter_by(infinitive=infinitive).first()

def chkengverb(infinitive):
    return getengverb(infinitive) is not None

def eng_trans_str(engverbinf):
    v = getengverb(engverbinf)
    return '; '.join([ t.spa_verb.infinitive for t in v.translations ])

def randomverb():
    return SpaVerb.query.order_by(func.random()).first().infinitive

def eng_randomverb():
    return EngVerb.query.order_by(func.random()).first().infinitive

def randomverbconj():
    p = Person.query.order_by(func.random()).first()
    v = SpaVerb.query.order_by(func.random()).first()

    # better solution needed for the next line
    t = Tense.query.filter_by(name='Present').first()

    return conjugate(v, t, p)

def randompronoun():
    p = Person.query.order_by(func.random()).first()
    return random.choice([ pron.pronoun for pron in p.pronouns ])

def pronoun2person(pronoun):
    pron = Pronoun.query.filter_by(pronoun=pronoun).first()
    return pron.person

def randomtense():
    t = Tense.query.order_by(func.random()).first()
    return t.name

def randompronouns(num):
    if num < 1 or num > 5:
        raise ValueError(f'{num} is not between 1 and 5')

    persons = Person.query.order_by(func.random()).limit(num)
    return [ random.choice(list(p.pronouns)).pronoun for p in persons ]
