from sqlalchemy import Column, DateTime, String, Integer, text, ForeignKey, Boolean, ARRAY
from sqlalchemy.orm import relationship
from sqlalchemy.dialects.postgresql import ENUM as SqlEnum, HSTORE
from enum import Enum as PyEnum

from load.projects.cloud.loadtesting.db.connection import BASE


class Status(PyEnum):
    # should be in sync with:
    # https://a.yandex-team.ru/arc/trunk/arcadia/load/projects/yandex-tank/yandextank/common/util.py?rev=r8559060#L855

    CREATED = 'CREATED'
    FAILED = 'FAILED'

    INITIATED = 'INITIATED'
    PREPARING = 'PREPARING'
    WAITING_FOR_A_COMMAND_TO_RUN = 'WAITING_FOR_A_COMMAND_TO_RUN'
    RUNNING = 'RUNNING'
    FINISHING = 'FINISHING'
    FINISHED = 'FINISHED'
    POST_PROCESS = 'POST_PROCESS'
    STOPPING = 'STOPPING'
    STOPPED = 'STOPPED'
    AUTOSTOPPED = 'AUTOSTOPPED'
    NOT_FOUND = 'NOT_FOUND'


class Generator(PyEnum):
    GENERATOR_UNSPECIFIED = 'GENERATOR_UNSPECIFIED'
    PHANTOM = 'PHANTOM'
    PANDORA = 'PANDORA'


class JobTable(BASE):
    __tablename__ = 'jobs'
    __table_args__ = {'extend_existing': True}

    n = Column('n', Integer(), primary_key=True, autoincrement=True)

    id = Column('id', String(50), unique=True)
    folder_id = Column('folder_id', String(50))
    name = Column('name', String)
    description = Column('description', String)
    labels = Column('labels', HSTORE)

    status = Column('status', SqlEnum(*[s.value for s in Status], name='jobs_statuses'))
    status_updated_at = Column('status_updated_at', DateTime)
    created_at = Column('created_at', DateTime, nullable=False, server_default=text("now()"))
    run_at = Column('run_at', DateTime, nullable=False, server_default=text("now()"))
    started_at = Column('started_at', DateTime)
    finished_at = Column('finished_at', DateTime)
    updated_at = Column('updated_at', DateTime)

    imbalance_point = Column('imbalance_point', Integer)
    imbalance_ts = Column('imbalance_ts', DateTime)

    target_address = Column('target_address', String(50))
    target_port = Column('target_port', Integer)
    version = Column('version', String(50))

    generator = Column('generator', SqlEnum(*[s.value for s in Generator], name='generators_enum'))
    cases = Column('cases', ARRAY(String))
    favorite = Column('favorite', Boolean, default=False)

    config = relationship('JobConfigTable', back_populates="job", uselist=False, enable_typechecks=False)

    tank_id = Column(String, ForeignKey('tanks.id', ondelete='SET NULL'))
    tank = relationship('TankTable', back_populates='jobs')
    errors = Column('errors', ARRAY(String))
    internal_tank_error = Column('internal_tank_error', String)

    logging_log_group_id = Column('logging_log_group_id', String(50))

    def __str__(self):
        return f'Job: job_id={self.id}, job_n={self.n}'
