#
#   Imandra Inc.
#
#   speclogician/presentation/preview/fixtures/data_artifact.py
#

from __future__ import annotations

from speclogician.presentation.ctx import RenderCtx
from speclogician.presentation.models.data_artifact import DataArtifactCorePM, DocRefPM, SrcCodeRefPM
from speclogician.presentation.renderers.data_artifact import (
    render_doc_ref,
    render_src_code_ref,
)

# -----------------------------------------------------------------------------
# Shared helpers
# -----------------------------------------------------------------------------

def _core(*, art_id: str) -> DataArtifactCorePM:
    return DataArtifactCorePM(art_id=art_id)


# -----------------------------------------------------------------------------
# DocRefPM fixtures
# -----------------------------------------------------------------------------

def minimal_doc_ref_pm() -> DocRefPM:
    return DocRefPM(
        core=_core(art_id="00000000-0000-0000-0000-000000000000"),
        text="",
        meta=None,
    )


def typical_doc_ref_pm() -> DocRefPM:
    return DocRefPM(
        core=_core(art_id="11111111-1111-1111-1111-111111111111"),
        text="Order must be rejected if quantity exceeds max order size.",
        meta="spec:order_limits; source=confluence; section=Risk Checks",
    )


def edge_doc_ref_pm() -> DocRefPM:
    return DocRefPM(
        core=_core(art_id="99999999-9999-9999-9999-999999999999"),
        text=(
            "A very long doc note that should wrap nicely and still be readable. "
            "It may contain bullet-like text, punctuation, and ‘quoted’ phrases.\n\n"
            "- Must preserve meaning\n"
            "- Must keep formatting\n"
            "- Should not overflow tables\n"
        ),
        meta=(
            "url=https://example.com/really/long/path/to/a/doc\n"
            "tags=risk,limits,edge-case\n"
            "owner=QA\n"
        ),
    )


def make_doc_ref_pm(ctx: RenderCtx, variant: str) -> DocRefPM:
    match variant:
        case "minimal":
            return minimal_doc_ref_pm()
        case "edge":
            return edge_doc_ref_pm()
        case _:
            return typical_doc_ref_pm()


# -----------------------------------------------------------------------------
# SrcCodeRefPM fixtures
# -----------------------------------------------------------------------------

def minimal_src_code_ref_pm() -> SrcCodeRefPM:
    return SrcCodeRefPM(
        core=_core(art_id="00000000-0000-0000-0000-000000000000"),
        src_code="",
        language=None,
        file_path=None,
        iml_code=None,
        meta=None,
    )


def typical_src_code_ref_pm(*, with_iml: bool = True) -> SrcCodeRefPM:
    return SrcCodeRefPM(
        core=_core(art_id="22222222-2222-2222-2222-222222222222"),
        src_code=(
            "def check_qty(order):\n"
            "    return order.qty <= 10000\n"
        ),
        language="python",
        file_path="risk/checks/order_limits.py",
        iml_code=(
            "let check_qty (o: order) : bool = o.qty <= 10000"
            if with_iml
            else None
        ),
        meta="repo=speclogician; commit=abc123; kind=snippet",
    )


def edge_src_code_ref_pm() -> SrcCodeRefPM:
    return SrcCodeRefPM(
        core=_core(art_id="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"),
        src_code=(
            "class RiskEngine:\n"
            "    def check(self, order, market_data, limits):\n"
            "        # extremely long snippet to stress wrapping\n"
            + ("        # line\n" * 60)
            + "        return True\n"
        ),
        language="python",
        file_path=("very/long/path/" * 6) + "risk_engine.py",
        iml_code=(
            "type order = { qty : int }\n"
            "let check (o: order) : bool = o.qty > 0\n"
            + ("(* comment *)\n" * 40)
        ),
        meta=(
            "repo=monorepo\n"
            "component=risk_engine\n"
            "note=this meta is multi-line to stress rendering\n"
        ),
    )


def make_src_code_ref_pm(ctx: RenderCtx, variant: str) -> SrcCodeRefPM:
    match variant:
        case "minimal":
            return minimal_src_code_ref_pm()
        case "edge":
            return edge_src_code_ref_pm()
        case _:
            return typical_src_code_ref_pm()
        
def render_doc(pm: DocRefPM, ctx: RenderCtx):
    return render_doc_ref(pm, ctx=ctx)


def render_src(pm: SrcCodeRefPM, ctx: RenderCtx):
    return render_src_code_ref(pm, ctx=ctx)