from __future__ import annotations
import tempfile
from pathlib import Path
import duckdb

from .type_mapper import TypeMapper
from expression.transpiler import ExpressionTranspiler


class RunContext:
    def __init__(
        self,
        workflow_dir: str,
        verbose: bool = False,
        output_dir: str | None = None,
        params: dict | None = None,
    ):
        self.workflow_dir = Path(workflow_dir)
        self.verbose = verbose
        self.output_dir: Path | None = Path(output_dir) if output_dir else None
        self.duckdb_con = duckdb.connect(":memory:")
        self.temp_dir = Path(tempfile.mkdtemp(prefix="alteryx_runner_"))
        self.type_mapper = TypeMapper()
        self.transpiler = ExpressionTranspiler(self.duckdb_con)
        self.constants: dict = params or {}

    def resolve_path(self, path: str) -> Path:
        # Normalise Windows backslashes so relative segments like .. work on
        # POSIX platforms (workflow XMLs are authored on Windows).
        path = path.replace("\\", "/")
        path = path.replace("%temp%", str(self.temp_dir) + "/")
        path = path.replace("%Desktop%", str(Path.home() / "Desktop") + "/")
        # Substitute workflow constants
        for k, v in self.constants.items():
            path = path.replace(f"%{k}%", v)
        p = Path(path)
        if not p.is_absolute():
            p = self.workflow_dir / p
        # If output_dir override active, remap file-write destinations
        return p

    def resolve_output_path(self, path: str) -> Path:
        p = self.resolve_path(path)
        if self.output_dir is not None:
            return self.output_dir / p.name
        return p

    def __del__(self):
        try:
            self.duckdb_con.close()
        except Exception:
            pass
