use db::{Db, fields, seed, vocab};
use domain::{AuthorityKind, FieldType};
use sqlx::PgPool;

#[sqlx::test]
async fn seed_creates_vocabularies_and_field_definitions(pool: PgPool) {
    let db = Db::from_pool(pool);

    let mut tx = db.pool().begin().await.unwrap();
    seed::seed_spectrum_cataloguing(&mut tx).await.unwrap();
    tx.commit().await.unwrap();

    for key in ["material", "object_name", "technique"] {
        assert!(
            vocab::vocabulary_by_key(db.pool(), key)
                .await
                .unwrap()
                .is_some(),
            "vocabulary {key} should be seeded"
        );
    }

    let material_vocab = vocab::vocabulary_by_key(db.pool(), "material")
        .await
        .unwrap()
        .unwrap();
    let material_field = fields::field_definition_by_key(db.pool(), "material")
        .await
        .unwrap()
        .unwrap();
    assert_eq!(
        material_field.field_type,
        FieldType::Term {
            vocabulary_id: material_vocab.id
        }
    );
    assert_eq!(material_field.group_key.as_deref(), Some("description"));

    let place = fields::field_definition_by_key(db.pool(), "production_place")
        .await
        .unwrap()
        .unwrap();
    assert_eq!(
        place.field_type,
        FieldType::Authority {
            kind: Some(AuthorityKind::Place)
        }
    );

    let title = fields::field_definition_by_key(db.pool(), "title")
        .await
        .unwrap()
        .unwrap();
    assert_eq!(title.field_type, FieldType::LocalizedText);
    let date = fields::field_definition_by_key(db.pool(), "production_date")
        .await
        .unwrap()
        .unwrap();
    assert_eq!(date.field_type, FieldType::Date);

    assert_eq!(
        fields::list_field_definitions(db.pool())
            .await
            .unwrap()
            .len(),
        12
    );
}

#[sqlx::test]
async fn seed_is_idempotent(pool: PgPool) {
    let db = Db::from_pool(pool);

    for _ in 0..2 {
        let mut tx = db.pool().begin().await.unwrap();
        seed::seed_spectrum_cataloguing(&mut tx).await.unwrap();
        tx.commit().await.unwrap();
    }

    assert_eq!(
        fields::list_field_definitions(db.pool())
            .await
            .unwrap()
            .len(),
        12
    );
    for key in ["material", "object_name", "technique"] {
        assert!(
            vocab::vocabulary_by_key(db.pool(), key)
                .await
                .unwrap()
                .is_some(),
            "vocabulary {key} should remain after re-seeding"
        );
    }
}
