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

from sqlalchemy import UniqueConstraint
from sqlalchemy.sql.expression import func

from nitrate import db
from nitrate.auth.models import User
from nitrate.plans.models import Plan
from nitrate.cases.models import Case
from nitrate.management.models import Build


run_env_value_association = db.Table(
    'nitrate_run_env_value_association',
    db.Column('run_id', db.Integer,
              db.ForeignKey('nitrate_runs.id'), nullable=False),
    db.Column('env_value_id', db.Integer,
              db.ForeignKey('nitrate_env_values.id'), nullable=False),
    UniqueConstraint('run_id', 'env_value_id'),
    )


run_tag_association = db.Table('nitrate_run_tag_association',
    db.Column('tag_id', db.Integer,
              db.ForeignKey('nitrate_tags.id'), nullable=False),
    db.Column('run_id', db.Integer,
              db.ForeignKey('nitrate_runs.id'), nullable=False),
    UniqueConstraint('tag_id', 'run_id'),
    )


class Run(db.Model):
    __tablename__ = 'nitrate_runs'

    id = db.Column(db.Integer, primary_key=True)
    summary = db.Column(db.String(255), nullable=False)
    notes = db.Column(db.Text, nullable=False, default='')
    estimated_time = db.Column(db.String(30), nullable=False, default=0)
    start_date = db.Column(db.DateTime, nullable=False, index=True)
    stop_date = db.Column(db.DateTime, nullable=False, index=True)

    plan_id = db.Column(db.Integer, db.ForeignKey(Plan.id), nullable=False)
    plan = db.relationship('Plan', backref=db.backref('runs', lazy='dynamic'))

    build_id = db.Column(db.Integer, db.ForeignKey(Build.id), nullable=False)
    build = db.relationship('Build',
                            backref=db.backref('runs', lazy='dynamic'))

    manager_id = db.Column(db.Integer, db.ForeignKey(User.id), nullable=False)
    manager = db.relationship('User',
        backref=db.backref('my_managed_runs', lazy='dynamic'))

    default_tester_id = db.Column(db.Integer, db.ForeignKey(User.id),
                                  nullable=False)
    default_tester = db.relationship('User',
        backref=db.backref('my_runs', lazy='dynamic'))

    env_values = db.relationship('EnvValue',
                                 secondary=run_env_value_association,
                                 backref=db.backref('runs', lazy='dynamic'))

    tags = db.relationship('Tag',
                           secondary=run_tag_association,
                           backref=db.backref('runs', lazy='dynamic'))

    created_on = db.Column(db.DateTime, nullable=False)
    updated_on = db.Column(db.DateTime, nullable=False)


CASE_RUN_COMPLETE_STATUSS = ('PASSED', 'ERROR', 'FAILED', 'WAIVED')
CASE_RUN_FAILURE_STATUSS = ('ERROR', 'FAILED')
CASE_RUN_IDLE_STATUSS = ('IDLE',)


class CaseRunStatus(db.Model):
    __tablename__ = 'nitrate_case_run_statuss'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(60), unique=True, nullable=False, default='')
    description = db.Column(db.Text, nullable=False, default='')
    auto_blinddown = db.Column(db.Boolean, nullable=False, default=True)

    created_on = db.Column(db.DateTime, nullable=False)
    updated_on = db.Column(db.DateTime, nullable=False)


class CaseRun(db.Model):
    __tablename__ = 'nitrate_case_runs'

    id = db.Column(db.Integer, primary_key=True)

    assignee_id = db.Column(db.Integer, db.ForeignKey(User.id), nullable=True)
    assignee = db.relationship(
        'User', backref=db.backref('case_runs_assigned_to_me', lazy='dynamic'))

    tested_by_id = db.Column(db.Integer, db.ForeignKey(User.id),
                             nullable=False)
    tested_by = db.relationship(
        'User', backref=db.backref('case_runs_tested_by_me', lazy='dynamic'))

    case_text_version = db.Column(db.Integer, nullable=False)
    running_date = db.Column(db.DateTime, nullable=False)
    close_date = db.Column(db.DateTime, nullable=False)
    notes = db.Column(db.Text, nullable=False, default='')

    run_id = db.Column(db.Integer, db.ForeignKey(Run.id), nullable=False)
    run = db.relationship('Run',
                          backref=db.backref('case_runs', lazy='dynamic'))

    case_id = db.Column(db.Integer, db.ForeignKey(Case.id), nullable=False)
    case = db.relationship('Case',
                          backref=db.backref('case_runs', lazy='dynamic'))

    status_id = db.Column(db.Integer, db.ForeignKey(CaseRunStatus.id),
                          nullable=False)
    status = db.relationship('CaseRunStatus',
                             backref=db.backref('case_runs', lazy='dynamic'))

    build_id = db.Column(db.Integer, db.ForeignKey(Build.id), nullable=False)
    build = db.relationship('Build',
                            backref=db.backref('case_runs', lazy='dynamic'))

    created_on = db.Column(db.DateTime, nullable=False)
    updated_on = db.Column(db.DateTime, nullable=False)
