"""Steps for TDD bug-capture scenario #989.

This scenario intentionally fails until the bugfix branch for #989 adds
corruption-specific handling around automation profile JSON decoding.
"""

from __future__ import annotations

import json
from datetime import UTC, datetime
from typing import Any

from behave import given, then, when
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

from cleveragents.infrastructure.database.models import (
    AutomationProfileModel,
    Base,
)
from cleveragents.infrastructure.database.repositories import (
    AutomationProfileRepository,
)


def _now_iso() -> str:
    return datetime.now(UTC).isoformat()


@given("an automation profile repository row with corrupt safety_json for bug 989")
def step_given_corrupt_safety_json_row(context: Any) -> None:
    """Persist a row that reproduces the malformed JSON decode path in _to_domain."""
    engine = create_engine("sqlite+pysqlite:///:memory:", future=True)
    Base.metadata.create_all(bind=engine)
    factory = sessionmaker(bind=engine, expire_on_commit=False, future=True)

    now_iso = _now_iso()
    with factory() as session:
        session.add(
            AutomationProfileModel(
                name="bug-989-corrupt-json",
                description="Corrupt JSON regression fixture",
                schema_version="1.0",
                auto_strategize=0.0,
                auto_execute=0.0,
                auto_apply=0.0,
                auto_decisions_strategize=0.0,
                auto_decisions_execute=0.0,
                auto_validation_fix=0.0,
                auto_strategy_revision=0.0,
                auto_reversion_from_apply=0.0,
                auto_child_plans=0.0,
                auto_retry_transient=0.0,
                auto_checkpoint_restore=0.0,
                require_sandbox=True,
                require_checkpoints=True,
                allow_unsafe_tools=False,
                # Deliberately malformed JSON (missing closing brace)
                safety_json='{"require_sandbox": true',
                guards_json=None,
                created_at=now_iso,
                updated_at=now_iso,
            )
        )
        session.commit()

    context.tdd_989_repo = AutomationProfileRepository(factory)
    context.tdd_989_error = None


@when("the corrupt automation profile is fetched by name for bug 989")
def step_when_fetch_corrupt_profile(context: Any) -> None:
    """Execute repository get path that currently leaks JSONDecodeError."""
    repo: AutomationProfileRepository = context.tdd_989_repo
    try:
        repo.get_by_name("bug-989-corrupt-json")
    except Exception as exc:
        context.tdd_989_error = exc


@then(
    "a corruption-specific domain error should be raised instead of JSONDecodeError for bug 989"
)
def step_then_domain_specific_error(context: Any) -> None:
    """Assert expected post-fix behavior (fails today while bug exists)."""
    err = context.tdd_989_error
    assert err is not None, (
        "Expected a corruption-specific domain error, but no error was raised"
    )
    assert not isinstance(err, json.JSONDecodeError), (
        "Expected a domain-specific corruption error, "
        f"but raw JSONDecodeError leaked: {err}"
    )
    name_or_message = f"{type(err).__name__} {err}".lower()
    assert "corrupt" in name_or_message, (
        "Expected corruption-specific error semantics (type/message containing 'corrupt'), "
        f"got {type(err).__name__}: {err}"
    )
