"""Shared fixtures for test-runner tests."""

from __future__ import annotations

import shutil
import textwrap
from pathlib import Path

import pytest

FIXTURES_DIR = Path(__file__).parent / "fixtures"


@pytest.fixture()
def tmp_project(tmp_path: Path) -> Path:
    """Create a minimal SCAI project directory tree in *tmp_path*.

    Layout::

        tmp_path/
            settings/test_config.yaml
            artifacts/master/dbo/procedure/GetProducts/test/getproducts.a1b2c3d4.yml
            artifacts/master/dbo/procedure/GetCustomerOrders/test/getcustomerorders.b2c3d4e5.yml
    """
    # settings
    settings_dir = tmp_path / "settings"
    settings_dir.mkdir()
    (settings_dir / "test_config.yaml").write_text(textwrap.dedent("""\
        source_platform: sqlserver
        target_platform: snowflake
    """))

    # artifacts -- simple procedure
    simple_dir = tmp_path / "artifacts" / "master" / "dbo" / "procedure" / "GetProducts" / "test"
    simple_dir.mkdir(parents=True)
    shutil.copy(FIXTURES_DIR / "simple_procedure.yml", simple_dir / "getproducts.a1b2c3d4.yml")

    # artifacts -- parameterized procedure
    param_dir = tmp_path / "artifacts" / "master" / "dbo" / "procedure" / "GetCustomerOrders" / "test"
    param_dir.mkdir(parents=True)
    shutil.copy(FIXTURES_DIR / "parameterized_procedure.yml", param_dir / "getcustomerorders.b2c3d4e5.yml")

    return tmp_path


@pytest.fixture()
def tmp_project_with_dml(tmp_project: Path) -> Path:
    """Extend *tmp_project* with a DML procedure that has modifies_data/affected_tables."""
    dml_dir = tmp_project / "artifacts" / "master" / "dbo" / "procedure" / "InsertColor" / "test"
    dml_dir.mkdir(parents=True)
    shutil.copy(FIXTURES_DIR / "dml_procedure.yml", dml_dir / "insertcolor.e5f6g7h8.yml")
    return tmp_project


@pytest.fixture()
def tmp_project_with_rpt(tmp_project: Path) -> Path:
    """Extend *tmp_project* with an RPT-schema test YAML file."""
    rpt_dir = tmp_project / "artifacts" / "master" / "rpt" / "procedure" / "GetProducts" / "test"
    rpt_dir.mkdir(parents=True)
    shutil.copy(FIXTURES_DIR / "rpt_procedure.yml", rpt_dir / "getproducts.c3d4e5f6.yml")
    return tmp_project


@pytest.fixture()
def tmp_project_with_output_params(tmp_project: Path) -> Path:
    """Extend *tmp_project* with a procedure that has output parameters."""
    out_dir = (
        tmp_project / "artifacts" / "master" / "dbo" / "procedure"
        / "GetProductDetails" / "test"
    )
    out_dir.mkdir(parents=True)
    shutil.copy(
        FIXTURES_DIR / "output_parameters_procedure.yml",
        out_dir / "getproductdetails.d4e5f6g7.yml",
    )
    return tmp_project


@pytest.fixture()
def tmp_project_with_redshift_cursor_output(tmp_path: Path) -> Path:
    """Create a minimal Redshift project with a REFCURSOR INOUT parameter test file.

    Uses ``redshift_cursor_output.yml`` (get_sales_by_region with ``rs_out``
    INOUT REFCURSOR).  Source platform is set to ``redshift`` so the capture
    runner renders fetch statements via ``fetch_cursor_redshift.sql.j2``.
    """
    settings_dir = tmp_path / "settings"
    settings_dir.mkdir()
    (settings_dir / "test_config.yaml").write_text(textwrap.dedent("""\
        source_platform: redshift
        target_platform: snowflake
    """))
    proc_dir = (
        tmp_path / "artifacts" / "dev" / "public"
        / "procedure" / "get_sales_by_region" / "test"
    )
    proc_dir.mkdir(parents=True)
    shutil.copy(
        FIXTURES_DIR / "redshift_cursor_output.yml",
        proc_dir / "get_sales_by_region.a1b2c3d4.yml",
    )
    return tmp_path


@pytest.fixture()
def tmp_project_with_redshift_output_params(tmp_path: Path) -> Path:
    """Create a minimal Redshift project with a scalar OUT parameter test file.

    Uses ``redshift_scalar_output.yml`` (fibonacci with ``result`` OUT param).
    Source platform is set to ``redshift`` so the capture runner uses the
    Redshift dialect template and routes through ``_extract_output_params``.
    """
    settings_dir = tmp_path / "settings"
    settings_dir.mkdir()
    (settings_dir / "test_config.yaml").write_text(textwrap.dedent("""\
        source_platform: redshift
        target_platform: snowflake
    """))
    fib_dir = (
        tmp_path / "artifacts" / "dev" / "public"
        / "procedure" / "fibonacci" / "test"
    )
    fib_dir.mkdir(parents=True)
    shutil.copy(
        FIXTURES_DIR / "redshift_scalar_output.yml",
        fib_dir / "fibonacci.a1b2c3d4.yml",
    )
    return tmp_path


@pytest.fixture()
def tmp_project_with_step_based(tmp_path: Path) -> Path:
    """Create a project with step-based (v2) YAML test files.

    Layout::

        tmp_path/
            settings/test_config.yaml
            artifacts/master/dbo/procedure/GetProducts/test/getproducts.s1s2s3s4.yml  (step-based)
            artifacts/master/dbo/procedure/BuildReport/test/buildreport.s5s6s7s8.yml  (step-based)
            artifacts/master/dbo/procedure/GetProductDetails/test/getproductdetails.s9s0s1s2.yml  (step-based)
            artifacts/master/dbo/procedure/get_sales_by_region/test/getsalesbyregion.s3s4s5s6.yml  (step-based)
            artifacts/master/dbo/procedure/Dashboard/test/dashboard.s7s8s9s0.yml  (step-based)
    """
    settings_dir = tmp_path / "settings"
    settings_dir.mkdir()
    (settings_dir / "test_config.yaml").write_text(textwrap.dedent("""\
        source_platform: sqlserver
        target_platform: snowflake
    """))

    # step-based simple procedure
    simple_dir = (
        tmp_path / "artifacts" / "master" / "dbo" / "procedure"
        / "GetProducts" / "test"
    )
    simple_dir.mkdir(parents=True)
    shutil.copy(
        FIXTURES_DIR / "step_simple_procedure.yml",
        simple_dir / "getproducts.s1s2s3s4.yml",
    )

    # step-based table output procedure
    report_dir = (
        tmp_path / "artifacts" / "master" / "dbo" / "procedure"
        / "BuildReport" / "test"
    )
    report_dir.mkdir(parents=True)
    shutil.copy(
        FIXTURES_DIR / "step_table_output.yml",
        report_dir / "buildreport.s5s6s7s8.yml",
    )

    # step-based output parameters procedure
    details_dir = (
        tmp_path / "artifacts" / "master" / "dbo" / "procedure"
        / "GetProductDetails" / "test"
    )
    details_dir.mkdir(parents=True)
    shutil.copy(
        FIXTURES_DIR / "step_output_params.yml",
        details_dir / "getproductdetails.s9s0s1s2.yml",
    )

    # step-based cursor output procedure
    sales_dir = (
        tmp_path / "artifacts" / "master" / "dbo" / "procedure"
        / "get_sales_by_region" / "test"
    )
    sales_dir.mkdir(parents=True)
    shutil.copy(
        FIXTURES_DIR / "step_cursor_output.yml",
        sales_dir / "getsalesbyregion.s3s4s5s6.yml",
    )

    # step-based multi-result-set procedure
    dashboard_dir = (
        tmp_path / "artifacts" / "master" / "dbo" / "procedure"
        / "Dashboard" / "test"
    )
    dashboard_dir.mkdir(parents=True)
    shutil.copy(
        FIXTURES_DIR / "step_multi_result_set.yml",
        dashboard_dir / "dashboard.s7s8s9s0.yml",
    )

    return tmp_path


@pytest.fixture()
def tmp_project_mixed(tmp_project: Path) -> Path:
    """Extend *tmp_project* (v1) with a step-based (v2) YAML file.

    The resulting project contains both v1 and v2 files, ensuring discovery
    handles mixed formats.
    """
    step_dir = (
        tmp_project / "artifacts" / "master" / "dbo" / "procedure"
        / "InsertColor" / "test"
    )
    step_dir.mkdir(parents=True)
    shutil.copy(
        FIXTURES_DIR / "step_dml_procedure.yml",
        step_dir / "insertcolor.s1s2s3s4.yml",
    )
    return tmp_project
