# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2025 Oxford Quantum Circuits Ltd
from qat.backend.waveform_v1.codegen import PydWaveformV1Backend
from qat.engines.waveform_v1 import EchoEngine
from qat.frontend import AutoFrontendWithFlattenedIR
from qat.middleend.middleends import ExperimentalDefaultMiddleend
from qat.model.convert_purr import convert_purr_echo_hw_to_pydantic
from qat.model.target_data import TargetData
from qat.pipelines.pipeline import Pipeline
from qat.pipelines.updateable import PipelineConfig, UpdateablePipeline
from qat.purr.compiler.hardware_models import QuantumHardwareModel
from qat.purr.utils.logger import get_default_logger
from qat.runtime import SimpleRuntime
from qat.runtime.results_pipeline import (
    get_experimental_results_pipeline,
)

log = get_default_logger()


class EchoPipeline(UpdateablePipeline):
    """A pipeline that compiles programs using the :class:`PydWaveformV1Backend`
    and executes them using the :class:`EchoEngine`.

    An engine cannot be provided to the pipeline, as the EchoEngine is used directly.

        .. warning::

        This pipeline is experimental and still in progress. Please use with caution.
    """

    @staticmethod
    def _build_pipeline(
        config: PipelineConfig,
        model: QuantumHardwareModel,
        target_data: TargetData | None,
        engine: None = None,
    ) -> Pipeline:
        """Constructs a pipeline equipped with the :class:`PydWaveformV1Backend`
        and :class:`EchoEngine`."""

        if engine is not None:
            log.warning(
                "An engine was provided to the EchoPipeline, but it will be ignored. "
                "The EchoEngine is used directly."
            )

        target_data = target_data if target_data is not None else TargetData.default()
        pyd_model = convert_purr_echo_hw_to_pydantic(model)
        results_pipeline = get_experimental_results_pipeline(model, pyd_model)
        return Pipeline(
            model=model,
            target_data=target_data,
            frontend=AutoFrontendWithFlattenedIR(model),
            middleend=ExperimentalDefaultMiddleend(model, pyd_model, target_data),
            backend=PydWaveformV1Backend(pyd_model, model, target_data),
            runtime=SimpleRuntime(engine=EchoEngine(), results_pipeline=results_pipeline),
            name=config.name,
        )
