"""Recording transport for fixture-driven CASE tests."""

from __future__ import annotations

from typing import Any

from test_support.transport_base import BaseRecordingTransport
from test_support.transport_helpers import dump_model
from timeback_common import CasePaths

from ..types.responses import (
    CFAssociation,
    CFDocument,
    CFItem,
    CFPackage,
    CFPackageUploadResult,
    CFPackageUploadResultDetail,
    CFPackageUploadResultStats,
    CFPackageWithGroups,
    LinkURI,
)


def create_recording_transport(
    fail_request: dict[str, Any] | None = None,
    transport_config: dict[str, Any] | None = None,
) -> BaseRecordingTransport:
    """Create a transport-like object that records calls and returns stub responses."""
    return _CaseRecordingTransport(fail_request=fail_request, transport_config=transport_config)


class _CaseRecordingTransport(BaseRecordingTransport):
    """CASE-specific recording transport with CASE paths and stubs."""

    def __init__(self, **kwargs: Any) -> None:
        super().__init__(**kwargs)
        self.paths = CasePaths()
        self._apply_exclude_paths()

    def _default_get_stub(self, path: str) -> dict[str, Any]:  # noqa: ARG002
        return {
            "CFDocument": dump_model(_stub_document()),
            "CFDocuments": [dump_model(_stub_document())],
            "CFItem": dump_model(_stub_item()),
            "CFItems": [dump_model(_stub_item())],
            "CFAssociation": dump_model(_stub_association()),
            "CFPackage": dump_model(_stub_package()),
            "CFPackageWithGroups": dump_model(_stub_package_with_groups()),
        }

    def _default_post_stub(self, path: str) -> dict[str, Any]:  # noqa: ARG002
        return dump_model(_stub_upload_result())

    def _default_put_stub(self, path: str) -> dict[str, Any]:  # noqa: ARG002
        return dump_model(_stub_upload_result())


def _stub_link_uri() -> LinkURI:
    return LinkURI(sourcedId="stub-001", title="Stub", uri="urn:stub-001")


def _stub_document() -> CFDocument:
    return CFDocument(
        sourcedId="stub-doc-001",
        title="Stub Framework",
        uri="urn:stub-doc-001",
        creator="Stub Org",
        lastChangeDateTime="2024-01-01T00:00:00Z",
        CFPackageURI=_stub_link_uri(),
        frameworkType=None,
        caseVersion=None,
        officialSourceURL=None,
        subjectURI=None,
        adoptionStatus=None,
        statusStartDate=None,
        statusEndDate=None,
        licenseURI=None,
    )


def _stub_item() -> CFItem:
    return CFItem(
        sourcedId="stub-item-001",
        fullStatement="Stub item",
        CFItemType="Standard",
        uri="urn:stub-item-001",
        lastChangeDateTime="2024-01-01T00:00:00Z",
        alternativeLabel=None,
        humanCodingScheme=None,
        listEnumeration=None,
        abbreviatedStatement=None,
        conceptKeywords=None,
        conceptKeywordsURI=None,
        subjectURI=None,
        educationLevel=None,
        CFItemTypeURI=None,
        licenseURI=None,
        statusStartDate=None,
        statusEndDate=None,
        CFDocumentURI=None,
    )


def _stub_association() -> CFAssociation:
    return CFAssociation(
        sourcedId="stub-assoc-001",
        associationType="isChildOf",
        uri="urn:stub-assoc-001",
        originNodeURI=_stub_link_uri(),
        destinationNodeURI=_stub_link_uri(),
        lastChangeDateTime="2024-01-01T00:00:00Z",
        sequenceNumber=None,
        CFAssociationGroupingURI=None,
        CFDocumentURI=None,
    )


def _stub_package() -> CFPackage:
    return CFPackage(
        sourcedId="stub-pkg-001",
        CFDocument=_stub_document(),
        CFItems=[_stub_item()],
        CFAssociations=[_stub_association()],
    )


def _stub_package_with_groups() -> CFPackageWithGroups:
    return CFPackageWithGroups(
        sourcedId="stub-pkg-001",
        CFDocument=_stub_document(),
    )


def _stub_upload_result() -> CFPackageUploadResult:
    return CFPackageUploadResult(
        success=True,
        message="Package uploaded",
        result=CFPackageUploadResultDetail(
            documentId="stub-doc-001",
            stats=CFPackageUploadResultStats(documents=1, items=0, associations=0),
            success=True,
        ),
    )
