//! `JobRepo` smoke tests: create → progress → finish, list filters.

use kebab_core::{JobFilter, JobKind, JobRepo, JobStatus};
use kebab_store_sqlite::SqliteStore;
use serde_json::json;

mod common;

#[test]
fn create_then_progress_then_finish() {
    let env = common::TestEnv::new();
    let store = SqliteStore::open(&env.config()).unwrap();
    store.run_migrations().unwrap();

    let id = store
        .create(JobKind::Ingest, json!({"path": "notes/x.md"}))
        .unwrap();
    // Status starts pending.
    let row = store.list(&JobFilter::default()).unwrap();
    assert_eq!(row.len(), 1);
    assert_eq!(row[0].status, JobStatus::Pending);

    // First progress flips pending → running.
    store
        .update_progress(&id, json!({"processed": 1, "total": 10}))
        .unwrap();
    let row = store.list(&JobFilter::default()).unwrap();
    assert_eq!(row[0].status, JobStatus::Running);
    assert_eq!(row[0].progress.as_ref().unwrap()["total"], json!(10));

    // Finish with success.
    store.finish(&id, JobStatus::Succeeded, None).unwrap();
    let row = store.list(&JobFilter::default()).unwrap();
    assert_eq!(row[0].status, JobStatus::Succeeded);
    assert!(row[0].finished_at.is_some());
    assert!(row[0].error.is_none());
}

#[test]
fn finish_with_error_message_is_round_trippable() {
    let env = common::TestEnv::new();
    let store = SqliteStore::open(&env.config()).unwrap();
    store.run_migrations().unwrap();

    let id = store.create(JobKind::Embed, json!({})).unwrap();
    store
        .finish(&id, JobStatus::Failed, Some("boom: model not pulled"))
        .unwrap();

    let row = store.list(&JobFilter::default()).unwrap();
    assert_eq!(row[0].status, JobStatus::Failed);
    assert_eq!(
        row[0].error.as_deref(),
        Some("boom: model not pulled"),
        "error message must round-trip"
    );
}

#[test]
fn list_filters_status_and_kind() {
    let env = common::TestEnv::new();
    let store = SqliteStore::open(&env.config()).unwrap();
    store.run_migrations().unwrap();

    // Two ingest jobs (one finished succeeded, one pending) + one embed.
    let a = store.create(JobKind::Ingest, json!({"a": 1})).unwrap();
    let _b = store.create(JobKind::Ingest, json!({"b": 1})).unwrap();
    let _c = store.create(JobKind::Embed, json!({"c": 1})).unwrap();
    store.finish(&a, JobStatus::Succeeded, None).unwrap();

    let by_status_succeeded = store
        .list(&JobFilter {
            status: Some(JobStatus::Succeeded),
            kind: None,
        })
        .unwrap();
    assert_eq!(by_status_succeeded.len(), 1);
    assert_eq!(by_status_succeeded[0].kind, JobKind::Ingest);

    let by_kind_embed = store
        .list(&JobFilter {
            status: None,
            kind: Some(JobKind::Embed),
        })
        .unwrap();
    assert_eq!(by_kind_embed.len(), 1);
    assert_eq!(by_kind_embed[0].kind, JobKind::Embed);
}
