from sqlalchemy import Column, ForeignKey, Integer, String

from openlog.datamodel.imports.import_classes import (
    AutomatedImport,
    ImportProfile,
    ImportType,
    JobFrequency,
)


def create_import_profiles_base(Base: type, schema: str = "") -> type:
    """
    Create sqlalchemy table class for import profiles

    Args:
        Base: sqlalchemy declarative database
        schema: database schema

    Returns: sqlalchemy table class

    """

    params = {
        "__tablename__": "import_profiles",
        "id": Column("id", Integer, primary_key=True),
        "name": Column("name", String),
        "type": Column("type", String),
        "assay_name": Column("assay_name", String),
        "parameters": Column("parameters", String),
    }

    if schema:
        params["__table_args__"] = {"schema": schema}
    cls = type("ImportProfile", (Base,), params)
    cls.from_import_profile = from_import_profile
    cls.to_import_profile = to_import_profile
    return cls


def from_import_profile(self, import_profile: ImportProfile) -> None:
    """
    Define import profile column from ImportProfile

    Args:
        self: import profile table object
        import_profile: ImportProfile
    """
    self.id = import_profile.id
    self.name = import_profile.name
    self.type = import_profile.type.value
    self.assay_name = import_profile.assay_name
    self.parameters = import_profile.parameters

    return self


def to_import_profile(self) -> ImportProfile:
    """
    Create ImportProfile for import profile columns

    Args:
        self: import profile table object

    Returns:ImportProfile

    """
    return ImportProfile(
        id=self.id,
        name=self.name,
        # Enums need conversion from string
        type=ImportType(self.type),
        assay_name=self.assay_name,
        parameters=self.parameters,
    )


def create_automated_imports_base(Base: type, schema: str = "") -> type:
    """
    Create sqlalchemy table class for automated imports definition

    Args:
        Base: sqlalchemy declarative database
        schema: database schema

    Returns: sqlalchemy table class

    """
    params = {
        "__tablename__": "automated_imports",
        "id": Column("id", Integer, primary_key=True),
        "name": Column("name", String),
        "profile": Column(
            "profile",
            Integer,
            ForeignKey(
                "import_profiles.id" if schema == "" else f"{schema}.import_profiles.id"
            ),
        ),
        "source_folder": Column("source_folder", String),
        "person": Column("person", String),
        "dataset": Column("dataset", String),
        "frequency": Column("frequency", String),
        "log_folder": Column("log_folder", String),
        "creation_date": Column("creation_date", String),
        "last_run_date": Column("last_run_date", String),
        "run_count": Column("run_count", Integer),
        "failed_run_count": Column("failed_run_count", Integer),
    }
    if schema:
        params["__table_args__"] = {"schema": schema}
    cls = type("AutomatedImport", (Base,), params)
    cls.from_automated_import = from_automated_import
    cls.to_automated_import = to_automated_import
    return cls


def from_automated_import(self, automated_import: AutomatedImport) -> None:
    """
    Define automated_import column from AutomatedImport

    Args:
        self: automated_import table object
        automated_import: AutomatedImport
    """
    self.id = automated_import.id
    self.name = automated_import.name
    self.profile = automated_import.profile
    self.source_folder = automated_import.source_folder
    self.person = automated_import.person
    self.dataset = automated_import.dataset
    self.frequency = automated_import.frequency.to_json()
    self.log_folder = automated_import.log_folder
    self.creation_date = automated_import.creation_date
    self.last_run_date = automated_import.last_run_date
    self.run_count = automated_import.run_count
    self.failed_run_count = automated_import.failed_run_count

    return self


def to_automated_import(self) -> AutomatedImport:
    """
    Create AutomatedImport for automated_import columns

    Args:
        self: automated_import table object

    Returns:AutomatedImport

    """
    return AutomatedImport(
        id=self.id,
        name=self.name,
        profile=self.profile,
        source_folder=self.source_folder,
        person=self.person,
        dataset=self.dataset,
        frequency=JobFrequency.from_json(self.frequency),
        log_folder=self.log_folder,
        creation_date=self.creation_date,
        last_run_date=self.last_run_date,
        run_count=self.run_count,
        failed_run_count=self.failed_run_count,
    )
