from datetime import datetime

from sandwich.dialects import DialectHandler
from sandwich.modeling.dataclasses import ValidationResult

from .generators.schema_generator import SchemaGenerator
from .validators.abc_validator import Validator
from .validators.link_sat0_validator import LinkSat0Validator
from .generators.link_sat0_schema_generator import LinkSat0SchemaGenerator
from .validators.scd2_dim_validator import Scd2DimValidator
from .generators.scd2_dim_schema_generator import Scd2DimSchemaGenerator
from .validators.hub_based_validator import HubBasedValidator
from .generators.hub_schema_generator import HubSchemaGenerator
from .validators.multi_sat2_validator import MultiSat2Validator
from .generators.multi_sat2_schema_generator import MultiSat2SchemaGenerator

class StrategyFactory:
    _strategies = {
        "hub-sat2-dim2": (Scd2DimValidator, Scd2DimSchemaGenerator),
        "link-sat0": (LinkSat0Validator, LinkSat0SchemaGenerator),
        "hub": (HubBasedValidator, HubSchemaGenerator),
        "multi-sat2": (MultiSat2Validator, MultiSat2SchemaGenerator),
    }

    @classmethod
    def register_strategy(cls, template_name: str, validator_class, generator_class):
        cls._strategies[template_name] = (validator_class, generator_class)

    @classmethod
    def create_validator(cls, profile: str) -> Validator:
        if profile not in cls._strategies:
            available = ", ".join(cls._strategies.keys())
            raise ValueError(f"Unknown profile '{profile}'. Available templates: {available}")

        validator_class, _ = cls._strategies[profile]
        return validator_class(profile)

    @classmethod
    def create_generator(cls, dialect_handler: DialectHandler, validation_result: ValidationResult, registered_on: datetime) -> SchemaGenerator:
        profile = validation_result.profile
        if profile not in cls._strategies:
            available = ", ".join(cls._strategies.keys())
            raise ValueError(f"Unknown profile '{profile}'. Available templates: {available}")

        _, generator_class = cls._strategies[profile]
        return generator_class(dialect_handler, validation_result, registered_on)

    @classmethod
    def get_available_templates(cls) -> list[str]:
        return list(cls._strategies.keys())
