"""
Build a data-validation ``Context`` from test-runner configuration.

Constructs the full ``Context`` object that ``BaseValidationExecutor`` and
the individual validators need, without going through the heavyweight
``ArgumentsManagerBase`` pipeline.
"""

from __future__ import annotations

import tempfile
import uuid
from datetime import datetime, timezone
from pathlib import Path
from typing import Optional

from snowflake.snowflake_data_validation.configuration.model.configuration_model import (
    ConfigurationModel,
)
from snowflake.snowflake_data_validation.utils.constants import (
    COLUMN_DATATYPES_MAPPING_NAME_FORMAT,
    ExecutionMode,
    Platform,
)
from snowflake.snowflake_data_validation.utils.context import Context
from snowflake.snowflake_data_validation.utils.helpers.helper_templates import (
    HelperTemplates,
)
from snowflake.snowflake_data_validation.utils.model.templates_loader_manager import (
    TemplatesLoaderManager,
)

from test_runner.common.config import TestRunnerConfig
from test_runner.common.database_dialect import DatabaseDialect

from .output_handler import LoggingOutputHandler


# ---------------------------------------------------------------------------
# Dialect -> Platform mapping
# ---------------------------------------------------------------------------

_DIALECT_TO_PLATFORM: dict[DatabaseDialect, Platform] = {
    DatabaseDialect.SQL_SERVER: Platform.SQLSERVER,
    DatabaseDialect.TERADATA: Platform.TERADATA,
    DatabaseDialect.REDSHIFT: Platform.REDSHIFT,
    DatabaseDialect.SNOWFLAKE: Platform.SNOWFLAKE,
}


def _resolve_platform(dialect: DatabaseDialect) -> Platform:
    return _DIALECT_TO_PLATFORM.get(dialect, Platform.SQLSERVER)


# ---------------------------------------------------------------------------
# Template directory resolver
# ---------------------------------------------------------------------------

def _pkg_root() -> Path:
    import snowflake.snowflake_data_validation as _pkg
    return Path(_pkg.__file__).resolve().parent


def _templates_dir(platform: Platform) -> Path:
    return _pkg_root() / platform.value / "extractor" / "templates"


# ---------------------------------------------------------------------------
# Public API
# ---------------------------------------------------------------------------

def build_context(
    config: TestRunnerConfig,
    report_path: Optional[str] = None,
) -> Context:
    """Build a data-validation ``Context`` from the test-runner config.

    Args:
        config: Loaded ``TestRunnerConfig``.
        report_path: Optional directory for validation reports.
            Defaults to a temporary directory.

    Returns:
        A fully initialised ``Context`` ready for use with
        ``BaseValidationExecutor`` and the validators.
    """
    source_platform = Platform.SNOWFLAKE  # Both tables are in Snowflake (transient)
    target_platform = Platform.SNOWFLAKE

    if report_path is None:
        report_path = config.output_directory_path
    if report_path is None:
        report_path = tempfile.mkdtemp(prefix="test_runner_validate_")

    # Templates
    source_templates_dir = _templates_dir(source_platform)
    target_templates_dir = _templates_dir(target_platform)

    source_templates = TemplatesLoaderManager(
        templates_directory_path=source_templates_dir,
        platform=source_platform,
    )
    target_templates = TemplatesLoaderManager(
        templates_directory_path=target_templates_dir,
        platform=target_platform,
    )

    # Jinja SQL templates directory (we point to the source platform's dir)
    jinja_templates_path = str(source_templates_dir)

    # Type mapping
    mapping_filename = COLUMN_DATATYPES_MAPPING_NAME_FORMAT.format(
        source_platform=source_platform.value,
        target_platform=target_platform.value,
    )
    mapping_yaml = source_templates_dir / mapping_filename
    datatypes_mappings: dict[str, str] | None = None
    if mapping_yaml.exists():
        datatypes_mappings = (
            HelperTemplates.load_datatypes_mapping_templates_from_yaml(mapping_yaml)
        )

    # Minimal ConfigurationModel
    configuration = ConfigurationModel(
        source_platform=source_platform.value,
        target_platform=target_platform.value,
        output_directory_path=report_path,
        comparison_configuration={"tolerance": 0.001},
    )

    run_id = str(uuid.uuid4())[:8]
    run_start_time = datetime.now(timezone.utc).strftime("%Y%m%d_%H%M%S")

    return Context(
        configuration=configuration,
        report_path=report_path,
        templates_dir_path=jinja_templates_path,
        source_platform=source_platform,
        target_platform=target_platform,
        custom_output_handler=LoggingOutputHandler(),
        run_id=run_id,
        run_start_time=run_start_time,
        source_templates=source_templates,
        target_templates=target_templates,
        execution_mode=ExecutionMode.SYNC_VALIDATION,
        datatypes_mappings=datatypes_mappings,
    )
