"""Test spectral analyses following 1D and 3D methods."""

from pathlib import Path

import pytest
from gammapy.analysis import Analysis, AnalysisConfig
from gammapy.modeling.models import Models

TEST_CASES_DIR = Path(__file__).parent
ANALYSIS_CONFIG_DIR = TEST_CASES_DIR / "analysis_config"
DATA_DIR = TEST_CASES_DIR / "data" / "hess"


@pytest.mark.verifies_usecase("SUSS-UC-100-1.0")
def test_1d_analysis(tmp_path):
    """Test the 1D spectral analysis using HLI.

    Based on Crab sample from H.E.S.S. DL3 DR1.
    """
    cfg_path = ANALYSIS_CONFIG_DIR / "1d_analysis.yaml"
    config = AnalysisConfig.read(str(cfg_path))

    # Data reduction
    analysis = Analysis(config)
    analysis.get_observations()
    analysis.get_datasets()

    dl4_dataset_filename = tmp_path / "hess_dl4_datasets.yaml"
    analysis.datasets.write(dl4_dataset_filename, overwrite=True, checksum=False)
    assert dl4_dataset_filename.exists()

    # Spectral model fit
    model_str = """
    components:
    - name: crab
      type: SkyModel
      spectral:
        type: PowerLawSpectralModel
        parameters:
          - name: index
            frozen: false
            scale: 1.0
            unit: ''
            value: 2.6
          - name: amplitude
            frozen: false
            scale: 1.0
            unit: cm-2 s-1 TeV-1
            value: 5.0e-11
          - name: reference
            frozen: true
            scale: 1.0
            unit: TeV
            value: 1.0
    """
    model_1d = Models.from_yaml(model_str)
    analysis.set_models(model_1d)
    analysis.run_fit()

    # Model serialization
    fit_model_filename = tmp_path / "model-best-fit.yaml"
    analysis.models.write(fit_model_filename, overwrite=True)
    assert fit_model_filename.exists()

    # Flux points and serialization
    analysis.get_flux_points()
    fp_filename = tmp_path / "flux-points.fits"
    analysis.flux_points.write(fp_filename, overwrite=True)
    assert fp_filename.exists()


@pytest.mark.verifies_usecase("SUSS-UC-100-2.0")
def test_3d_analysis(tmp_path):
    """Test the 3D spectral analysis using HLI.

    Based on Crab sample from H.E.S.S. DL3 DR1.
    """
    cfg_path = ANALYSIS_CONFIG_DIR / "3d_analysis.yaml"
    config = AnalysisConfig.read(str(cfg_path))

    # Data reduction
    analysis = Analysis(config)
    analysis.get_observations()
    analysis.get_datasets()

    dl4_dataset_filename = tmp_path / "hess_dl4_datasets.yaml"
    analysis.datasets.write(dl4_dataset_filename, overwrite=True, checksum=False)
    assert dl4_dataset_filename.exists()

    model_str = """
    components:
    - name: crab
      type: SkyModel
      spectral:
        type: PowerLawSpectralModel
        parameters:
          - name: index
            frozen: false
            scale: 1.0
            unit: ''
            value: 2.6
          - name: amplitude
            frozen: false
            scale: 1.0
            unit: cm-2 s-1 TeV-1
            value: 5.0e-11
          - name: reference
            frozen: true
            scale: 1.0
            unit: TeV
            value: 1.0
      spatial:
        type: PointSpatialModel
        frame: icrs
        parameters:
        -   name: lon_0
            value: 83.633
            unit: deg
            frozen: false
        -   name: lat_0
            value: 22.014
            unit: deg
            frozen: false
    """
    model_3d = Models.from_yaml(model_str)
    analysis.set_models(model_3d)
    analysis.run_fit()

    # Model serialization
    fit_model_filename = tmp_path / "model-best-fit.yaml"
    analysis.models.write(fit_model_filename, overwrite=True)
    assert fit_model_filename.exists()


@pytest.mark.verifies_usecase("SUSS-UC-100-3.0")
def test_source_finding(tmp_path):
    """Implement source finding use case using CTA 1DC GC dataset."""
    import astropy.units as u
    from gammapy.datasets import MapDataset
    from gammapy.estimators import TSMapEstimator
    from gammapy.estimators.utils import find_peaks_in_flux_map
    from gammapy.modeling.models import SkyModel

    dataset = MapDataset.read("$GAMMAPY_DATA/cta-1dc-gc/cta-1dc-gc.fits.gz")
    model = SkyModel.create(spatial_model="point", spectral_model="pl")

    estimator = TSMapEstimator(
        model=model, kernel_width="1 deg", energy_edges=[0.1, 10] * u.TeV
    )
    maps = estimator.run(dataset)

    source_table = find_peaks_in_flux_map(maps, threshold=5, min_distance="0.2 deg")
    table_filename = tmp_path / "source_tables.fits"
    source_table.write(table_filename)

    assert len(source_table) == 7
    assert table_filename.exists()
