from enum import Enum
from typing import Optional, List
from datetime import datetime

import sqlalchemy

from pydantic import BaseModel 
from sqlalchemy import Column, String, Integer, DateTime, ForeignKey, Table
from sqlalchemy.orm import relationship

from poindexter.models import Base
from poindexter.models.CSE import CSE
from poindexter.models.APIKey import APIKey
from poindexter.models.Profile import Profile
from poindexter.models.Report import Report
from poindexter.models.Plugin import Plugin


Job_Plugin_Table = Table(
  'job_plugin_association',
  Base.metadata,
  Column('job_id', ForeignKey('jobs.id')),
  Column('plugin_id', ForeignKey('plugins.id'))
)


class JobStatus(Enum):
  CREATED = "CREATED"
  RUNNING = "RUNNING"
  ERROR = "ERROR"
  FINISHED = "FINISHED"


class JobCreate(BaseModel):
  name: str
  profile_id: int
  cse_id: int
  key_id: int


class JobUpdate(BaseModel):
  status: JobStatus


class Job(JobCreate):
  id: int
  status: JobStatus
  created: datetime
  profile: Profile
  cse: CSE
  key: APIKey
  report_id: Optional[int]
  report: Optional[Report]
  plugins: List[Plugin]
  class Config:
    orm_mode = True


class JobModel(Base):
  __tablename__ = 'jobs'
  id = Column(Integer, primary_key=True, index=True)
  name = Column(String)
  status = Column(sqlalchemy.Enum(JobStatus), default=JobStatus.CREATED)
  created = Column(DateTime, default=lambda: datetime.now())
  profile_id = Column(Integer, ForeignKey("profiles.id"))
  cse_id = Column(Integer, ForeignKey("cses.id"))
  key_id = Column(Integer, ForeignKey("keys.id"))
  report_id = Column(Integer, ForeignKey("reports.id"), nullable=True)
  profile = relationship("ProfileModel")
  cse = relationship("CSEModel")
  key = relationship("APIKeyModel")
  report = relationship("ReportModel")
  plugins = relationship("PluginModel", secondary=Job_Plugin_Table)
