###############################################################################
# (c) Copyright 2020 CERN for the benefit of the LHCb Collaboration           #
#                                                                             #
# This software is distributed under the terms of the GNU General Public      #
# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   #
#                                                                             #
# In applying this licence, CERN does not waive the privileges and immunities #
# granted to it by virtue of its status as an Intergovernmental Organization  #
# or submit itself to any jurisdiction.                                       #
###############################################################################
import os
from os.path import isfile, join

import pytest
from click.testing import CliRunner

import LbAPLocal
import LbAPLocal.testing
from fixture_loader import discover_fixtures
from LbAPLocal.cli import legacy_main as main

# ============================================================================
# CWL-based tests (primary) — auto-discovered from tests/fixtures/
# ============================================================================


def _cwl_test_params():
    """Auto-discover all fixtures and generate test parameters."""
    params = []
    for prod_name, fixture_set in discover_fixtures().items():
        for job_name in fixture_set.job_names:
            params.append(
                pytest.param(prod_name, job_name, id=f"{prod_name}/{job_name}")
            )
    return params


@pytest.mark.slow
@pytest.mark.parametrize(
    "cwl_fixture_set,job_name", _cwl_test_params(), indirect=["cwl_fixture_set"]
)
def test_cwl_test(
    data_pkg_repo, mock_dirac_calls, cwl_fixture_set, job_name, tmp_path, monkeypatch
):
    """Test the CWL-based execution path using LbAPCommon + dirac-cwl-run."""
    import typer

    from LbAPLocal.cli.main import cwl_test

    monkeypatch.setattr(
        LbAPLocal.cli,
        "get_auth_headers",
        lambda: dict(headers={"Authorization": "Bearer "}),
    )

    output_dir = tmp_path / "cwl_output"

    try:
        cwl_test(
            production_name=cwl_fixture_set.production_name,
            job_name=job_name,
            skip_validation=True,
            output_dir=output_dir,
            n_lfns=1,
        )
    except (typer.Exit, SystemExit) as e:
        exit_code = getattr(e, "exit_code", getattr(e, "code", 1))
        pytest.fail(f"cwl_test exited with code {exit_code}")

    # CWL workflow was generated
    cwl_files = list(output_dir.glob("*.cwl"))
    assert cwl_files, "No CWL workflow file generated"

    # Inputs and replica map were written by mock_dirac_calls
    inputs_files = list(output_dir.glob("*-inputs.yml"))
    assert inputs_files, "No CWL inputs file generated"
    replica_maps = list(output_dir.glob("*-replica-map.json"))
    assert replica_maps, "No replica map generated"

    # CWL output directory exists (runner executed)
    cwl_output = output_dir / "cwl_output"
    assert cwl_output.is_dir(), "CWL output directory not created"


# ============================================================================
# Legacy tests (deprecated, kept temporarily)
# ============================================================================


@pytest.mark.skip(reason="Legacy lb-prod-run path, replaced by test_cwl_test")
@pytest.mark.slow
@pytest.mark.vcr
@pytest.mark.parametrize(
    "name,n_events",
    [
        ("2016_MagDown_PromptMC_D02KK", 2444),
        ("2016_MagUp_PromptMC_D02KK", 2393),
        ("2016_MagDown_PromptMC_D02KK_noautoconf", 2444),
        ("2016_MagUp_PromptMC_D02KK_noautoconf", 2393),
    ],
)
def test_run_test(
    with_proxy, data_pkg_repo, with_data, name, n_events, monkeypatch, record_mode
):
    if record_mode == "none":
        monkeypatch.setattr(
            LbAPLocal.cli,
            "get_auth_headers",
            lambda: dict(headers={"Authorization": "Bearer "}),
        )
        monkeypatch.setattr(
            LbAPLocal.testing,
            "get_auth_headers",
            lambda: dict(headers={"Authorization": "Bearer "}),
        )

    runner = CliRunner()
    result = runner.invoke(main, ["test", "executabletests", name, "--no-validate"])
    assert result.exit_code == 0, result.stdout

    assert "Application Manager Finalized successfully" in result.stdout
    assert "Application Manager Terminated successfully" in result.stdout
    assert f"{n_events} events processed" in result.stdout
    assert "Summary of log messages" in result.stdout
    assert "General explanations" in result.stdout
    assert "Histograms are not being saved" in result.stdout

    assert "Output can be found in" in result.stdout
    output_dir = result.stdout.split("Output can be found in")[-1].strip()

    output_fn = join(output_dir, "00012345_00006789_1.D02KK.ROOT")
    assert isfile(output_fn)
    assert 100 * 1024 <= os.stat(output_fn).st_size <= 1024**2

    stdout_fn = join(output_dir, "stdout.log")
    assert isfile(stdout_fn)
    with open(stdout_fn, "rt") as fp:
        stdout = fp.read()
    assert "Application Manager Finalized successfully" in stdout
    assert "Application Manager Terminated successfully" in stdout
    assert f"{n_events} events processed" in stdout

    stderr_fn = join(output_dir, "stderr.log")
    assert isfile(stderr_fn)
