from sandwich.modeling.dataclasses import Dv2SystemInfo, StgInfo

from .base_validator import BaseValidator
from ...metadata import modeling_metadata


class MultiSat2Validator(BaseValidator):
    """Validation rules:\n
    1. `bk_` column(s) should exist\n
    2. only one `hk_` column is allowed\n
    3. `hk_<entity_name>` column cant have `<entity_name>` = own entity name
    4. `HashDiff` and `IsAvailable` columns are required for scd2
    5. own entity name should start with another entity name as a prefix
    6. `hk_<entity_name>` should have entity_name = another entity name
    """
    def __init__(self, profile: str):
        super().__init__(profile)
        self._on_validate_staging.append(self._validate_multi_sat_staging)

    @staticmethod
    def _validate_multi_sat_staging(stg_info: StgInfo, sys_info: Dv2SystemInfo) -> None:
        if len(stg_info.bk_keys) == 0:
            raise Exception("bk column(s) are required for `multi-sat2` validation")

        hk_count = len(stg_info.hk_keys)
        if hk_count == 0:
            raise Exception("hk column is required for `multi-sat2` validation")
        elif hk_count > 1:
            raise Exception(f"More than one hk column found in stg.{stg_info.stg_name}")

        hk_key = list(stg_info.hk_keys.items())[0]
        if hk_key[0] == f"hk_{stg_info.stg_name}":
            raise Exception(f"hk column has invalid name '{hk_key[0]}'")

        system_column_names = stg_info.sys_columns.keys()
        if modeling_metadata.hashdiff not in system_column_names:
            raise Exception(f"{modeling_metadata.hashdiff} column is required for `multi-sat2` validation")
        if modeling_metadata.is_available not in system_column_names:
            raise Exception(f"{modeling_metadata.is_available} column is required for `multi-sat2` validation")

        other_entity_name: str | None = None
        for entity in sys_info.entities_list:
            if stg_info.stg_name.startswith(entity.entity_name) and stg_info.stg_name != entity.entity_name:
                other_entity_name = entity.entity_name
        if not other_entity_name:
            raise Exception("`multi-sat2` entity name should have other entity name as a suffix")

        if hk_key[0] != f"hk_{other_entity_name}":
            raise Exception(f"hk column has invalid name '{hk_key[0]}', correct name is `{other_entity_name}`")
