"""Base compiler ABC and CompiledOutput container."""

from __future__ import annotations

from abc import ABC, abstractmethod
from dataclasses import dataclass, field
from datetime import datetime, timezone
from typing import Any, Dict, List, Optional

from databridge_core.sdk.core.types import CompiledArtifact


@dataclass
class CompiledOutput:
    """Complete compilation output for a workflow.

    Attributes:
        workflow: Source workflow name.
        artifacts: List of compiled Snowflake objects.
        deploy_script: Combined DDL script for deployment.
        rollback_script: Rollback DDL (DROP statements).
        metadata: Extra metadata (timestamps, compiler version).
    """

    workflow: str = ""
    artifacts: List[CompiledArtifact] = field(default_factory=list)
    deploy_script: str = ""
    rollback_script: str = ""
    metadata: Dict[str, Any] = field(default_factory=dict)

    def to_dict(self) -> Dict[str, Any]:
        return {
            "workflow": self.workflow,
            "artifacts": [a.to_dict() for a in self.artifacts],
            "deploy_script": self.deploy_script,
            "rollback_script": self.rollback_script,
            "metadata": self.metadata,
        }


class BaseCompiler(ABC):
    """Abstract base for all Snowflake object compilers.

    Subclasses implement ``compile()`` to generate specific object types
    (Dynamic Tables, Tasks, Stored Procs, etc.) from workflow parameters.

    Attributes:
        object_type: Snowflake object type (e.g. ``DYNAMIC TABLE``).
    """

    object_type: str = ""

    @abstractmethod
    def compile(
        self,
        workflow_name: str,
        params: Dict[str, Any],
        target_database: Optional[str] = None,
        target_schema: Optional[str] = None,
    ) -> List[CompiledArtifact]:
        """Compile workflow parameters into Snowflake DDL.

        Args:
            workflow_name: Source workflow name.
            params: Workflow parameters.
            target_database: Target Snowflake database.
            target_schema: Target Snowflake schema.

        Returns:
            List of CompiledArtifact with DDL statements.

        Raises:
            sdk.core.exceptions.CompilationError: On failure.
        """

    def _fqn(
        self,
        name: str,
        database: Optional[str] = None,
        schema: Optional[str] = None,
    ) -> str:
        """Build a fully-qualified Snowflake object name."""
        parts = []
        if database:
            parts.append(database)
        if schema:
            parts.append(schema)
        parts.append(name)
        return ".".join(parts)

    def _header(self, object_name: str) -> str:
        """Generate a standard DDL header comment."""
        ts = datetime.now(timezone.utc).isoformat()
        return (
            f"-- Generated by DataBridge SDK Compiler\n"
            f"-- Object: {object_name}\n"
            f"-- Timestamp: {ts}\n"
            f"-- Type: {self.object_type}\n"
        )
