"""Fixtures for the meta tests"""

from datetime import datetime

import pytest
from _pytest import tmpdir
from cg.apps.balsamic.fastq import FastqHandler as BalsamicFastqHandler
from cg.apps.housekeeper.hk import HousekeeperAPI
from cg.apps.scout.scoutapi import ScoutAPI
from cg.meta.workflow.mip import MipAnalysisAPI
from cg.store import Store
from tests.store_helpers import StoreHelpers


@pytest.fixture(scope="function", name="analysis_store")
def fixture_analysis_store(base_store: Store, analysis_family: dict) -> Store:
    """Setup a store instance for testing analysis API."""
    customer = base_store.customer("cust000")
    family = base_store.Family(
        data_analysis=analysis_family["data_analysis"],
        name=analysis_family["name"],
        panels=analysis_family["panels"],
        internal_id=analysis_family["internal_id"],
        priority="standard",
    )
    family.customer = customer
    base_store.add(family)
    application_version = base_store.application("WGTPCFC030").versions[0]
    for sample_data in analysis_family["samples"]:
        sample = base_store.add_sample(
            name=sample_data["name"],
            sex=sample_data["sex"],
            internal_id=sample_data["internal_id"],
            ticket=sample_data["ticket_number"],
            reads=sample_data["reads"],
            capture_kit=sample_data["capture_kit"],
        )
        sample.family = family
        sample.application_version = application_version
        sample.customer = customer
        base_store.add(sample)
    base_store.commit()
    for sample_data in analysis_family["samples"]:
        sample_obj = base_store.sample(sample_data["internal_id"])
        link = base_store.relate_sample(
            family=family,
            sample=sample_obj,
            status=sample_data["status"],
            father=base_store.sample(sample_data["father"]) if sample_data.get("father") else None,
            mother=base_store.sample(sample_data["mother"]) if sample_data.get("mother") else None,
        )
        base_store.add(link)
    base_store.commit()
    yield base_store


class MockLims:
    """Mock lims fixture"""

    lims = None

    def __init__(self):
        self.lims = self


class MockPath:
    def __init__(self, path):
        self.yaml = None

    def __call__(self, *args, **kwargs):
        return self

    def open(self):
        return dict()

    def joinpath(self, path):
        return path


class MockLogger:
    warnings = []

    def warning(self, text, *interpolations):

        self.warnings.append(text % interpolations)

    def get_warnings(self) -> list:
        return self.warnings


class MockTB:
    _get_trending_raises_keyerror = False

    def __init__(self):
        """Needed to initialise mock variables"""
        self._make_config_was_called = False

    def get_trending(self, mip_config_raw: dict, qcmetrics_raw: dict, sampleinfo_raw: dict) -> dict:
        if self._get_trending_raises_keyerror:
            raise KeyError("mockmessage")

        # Returns: dict: parsed data
        ### Define output dict
        outdata = {
            "analysis_sex": {"ADM1": "female", "ADM2": "female", "ADM3": "female"},
            "case": "yellowhog",
            "duplicates": {"ADM1": 13.525, "ADM2": 12.525, "ADM3": 14.525},
            "mapped_reads": {"ADM1": 98.8, "ADM2": 99.8, "ADM3": 97.8},
            "mip_version": "v4.0.20",
            "sample_ids": ["2018-20203", "2018-20204"],
            "genome_build": "37",
            "rank_model_version": "1.18",
        }

        return outdata

    def get_sampleinfo(self, analysis_obj):
        return ""

    def make_config(self, data, pipeline):
        """Mock the make_config"""
        self._make_config_was_called = True
        del pipeline
        return data


class MockBalsamicFastq(BalsamicFastqHandler):
    """Mock FastqHandler for analysis_api"""

    def __init__(self):
        super().__init__(config={"balsamic": {"root": tmpdir}})


@pytest.fixture(scope="function", name="mip_hk_store")
def fixture_mip_hk_store(
    helpers: StoreHelpers,
    real_housekeeper_api: HousekeeperAPI,
    timestamp: datetime,
    case_id: str,
) -> HousekeeperAPI:
    deliver_hk_bundle_data = {
        "name": case_id,
        "created": timestamp,
        "expires": timestamp,
        "files": [
            {
                "path": "tests/fixtures/apps/mip/dna/store/case_config.yaml",
                "archive": False,
                "tags": ["mip-config"],
            },
            {
                "path": "tests/fixtures/apps/mip/dna/store/case_qc_sample_info.yaml",
                "archive": False,
                "tags": ["sampleinfo"],
            },
            {
                "path": "tests/fixtures/apps/mip/case_qc_metrics.yaml",
                "archive": False,
                "tags": ["qcmetrics"],
            },
            {
                "path": "tests/fixtures/apps/mip/case_file.txt",
                "archive": False,
                "tags": ["case-tag"],
            },
            {
                "path": "tests/fixtures/apps/mip/sample_file.txt",
                "archive": False,
                "tags": ["sample-tag", "ADM1"],
            },
        ],
    }
    helpers.ensure_hk_bundle(real_housekeeper_api, deliver_hk_bundle_data, include=True)

    empty_deliver_hk_bundle_data = {
        "name": "case_missing_data",
        "created": timestamp,
        "expires": timestamp,
        "files": [
            {
                "path": "tests/fixtures/apps/mip/dna/store/empty_case_config.yaml",
                "archive": False,
                "tags": ["mip-config"],
            },
            {
                "path": "tests/fixtures/apps/mip/dna/store/empty_case_qc_sample_info.yaml",
                "archive": False,
                "tags": ["sampleinfo"],
            },
            {
                "path": "tests/fixtures/apps/mip/dna/store/empty_case_qc_metrics.yaml",
                "archive": False,
                "tags": ["qcmetrics"],
            },
            {
                "path": "tests/fixtures/apps/mip/case_file.txt",
                "archive": False,
                "tags": ["case-tag"],
            },
            {
                "path": "tests/fixtures/apps/mip/sample_file.txt",
                "archive": False,
                "tags": ["sample-tag", "ADM1"],
            },
        ],
    }
    helpers.ensure_hk_bundle(real_housekeeper_api, empty_deliver_hk_bundle_data, include=True)

    return real_housekeeper_api


@pytest.fixture(scope="function", name="analysis_api")
def fixture_analysis_api(
    analysis_store: Store, mip_hk_store: HousekeeperAPI, scout_api: ScoutAPI
) -> MipAnalysisAPI:
    """Setup an analysis API."""

    analysis_api = MipAnalysisAPI(
        db=analysis_store,
        hk_api=mip_hk_store,
        scout_api=scout_api,
        tb_api=MockTB(),
        lims_api=MockLims(),
        script="echo",
        pipeline="analyse rd_dna",
        conda_env="S_mip_rd-dna",
        root="/var/empty",
    )
    yield analysis_api
