from __future__ import annotations

from app.core.common.identifiers import new_governance_uid


def _write_spec():
    return {
        "schema_version": "1.0",
        "dataflow_uid": new_governance_uid(),
        "name": "materialize-orders",
        "nodes": [
            {
                "id": "write_orders",
                "type": "sql.execute",
                "data_source_uid": new_governance_uid(),
                "purpose": "write",
                "idempotency": {
                    "strategy": "partition_replace",
                    "key": "orders:${parameters.day}",
                },
                "config": {
                    "statement": "INSERT INTO daily_orders SELECT * FROM orders"
                },
            }
        ],
        "edges": [],
        "parameters": {},
    }


def _plan():
    return {
        "schema_version": "1.0",
        "timezone": "Asia/Shanghai",
        "triggers": [{"type": "manual"}],
        "max_concurrency": 1,
        "conflict_policy": "skip",
        "timeout_seconds": 600,
        "retry": {"max_attempts": 1, "delay_seconds": 0},
        "backfill": {"max_days": 1, "max_runs": 1},
    }


def test_production_write_candidate_requires_disabled_deploy_and_canary():
    from app.core.orchestration.policy import evaluate_candidate

    rejected = evaluate_candidate(
        _write_spec(),
        _plan(),
        environment="production",
        deploy_disabled=False,
        canary_required=False,
    )
    assert rejected.allowed is False
    assert rejected.risk == "high"
    assert "production candidate must deploy disabled" in rejected.reasons
    assert "production write candidate requires canary" in rejected.reasons

    accepted = evaluate_candidate(
        _write_spec(),
        _plan(),
        environment="production",
        deploy_disabled=True,
        canary_required=True,
    )
    assert accepted.allowed is True
    assert accepted.risk == "high"


def test_non_production_read_candidate_is_low_risk():
    from app.core.orchestration.policy import evaluate_candidate
    from tests.core.orchestration.test_spec import (
        valid_schedule_plan,
        valid_workflow_spec,
    )

    decision = evaluate_candidate(
        valid_workflow_spec(),
        valid_schedule_plan(),
        environment="test",
        deploy_disabled=True,
        canary_required=False,
    )

    assert decision.allowed is True
    assert decision.risk == "low"
    assert decision.reasons == ()
