use shepherd_cli::shepherd::dispatch::{
    LaneId, ReviewMode, ReviewResult, ReviewVerdict, Role, RunId,
};
use shepherd_cli::{
    REVIEW_REQUEST_SCHEMA, ReviewValidationRequest, validate_review_result_request,
};

fn review(mode: ReviewMode, role: Role, verdict: ReviewVerdict) -> ReviewResult {
    ReviewResult {
        schema: "shepherd.review-result/1".into(),
        run: RunId::new("v657").expect("run"),
        lane: Some(LaneId::new("l1-engine").expect("lane")),
        mode,
        reviewer_role: role,
        candidate_commit: "0123456789abcdef0123456789abcdef01234567".into(),
        input_digest: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa".into(),
        startup_skill: "reviewing".into(),
        skill_bundle_digest: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
            .into(),
        result_channel: "native-result".into(),
        verdict,
        findings: vec![],
        report_path: None,
    }
}

#[test]
fn cli_accepts_only_typed_role_correct_review_results() {
    let result = validate_review_result_request(ReviewValidationRequest {
        schema: REVIEW_REQUEST_SCHEMA.into(),
        review: review(ReviewMode::CriticPrehoc, Role::Critic, ReviewVerdict::Green),
    })
    .expect("Critic result validates");
    assert_eq!(result.reviewer_role, Role::Critic);

    let mut invalid = review(ReviewMode::CriticPrehoc, Role::Critic, ReviewVerdict::Green);
    invalid.report_path = Some("runs/v657/critic.md".into());
    assert!(
        validate_review_result_request(ReviewValidationRequest {
            schema: REVIEW_REQUEST_SCHEMA.into(),
            review: invalid,
        })
        .is_err()
    );

    let mut auditor = review(
        ReviewMode::AuditorPosthoc,
        Role::Auditor,
        ReviewVerdict::Pass,
    );
    auditor.report_path = Some("runs/v657/auditor.md".into());
    validate_review_result_request(ReviewValidationRequest {
        schema: REVIEW_REQUEST_SCHEMA.into(),
        review: auditor.clone(),
    })
    .expect("Auditor report path with observed report-write validates");
    auditor.report_path = None;
    assert!(
        validate_review_result_request(ReviewValidationRequest {
            schema: REVIEW_REQUEST_SCHEMA.into(),
            review: auditor,
        })
        .is_err()
    );
}