use serde::Deserialize;
use rsstacker::engine::board::Board;
use rsstacker::engine::prng::generate_sequence;

#[derive(Deserialize)]
struct BoardCase {
    name: String,
    seed: i64,
    queue_len: usize,
    actions: Vec<String>,
    grid: Vec<String>,
    hold: Option<String>,
    lines_cleared: u32,
    pieces_placed: u32,
}

#[derive(Deserialize)]
struct BoardFixture {
    cases: Vec<BoardCase>,
}

#[test]
fn board_matches_fixture_states() {
    let raw = std::fs::read_to_string("tests/fixtures/board.json").unwrap();
    let fixture: BoardFixture = serde_json::from_str(&raw).unwrap();
    assert!(!fixture.cases.is_empty());
    for case in fixture.cases {
        let mut board = Board::new(generate_sequence(case.seed, case.queue_len, false));
        for key in &case.actions {
            if board.current.is_none() {
                break;
            }
            board.apply_key(key);
        }
        let got_grid: Vec<String> = (0..40).map(|r| board.row_string(r)).collect();
        assert_eq!(got_grid, case.grid, "grid mismatch in case {}", case.name);
        let got_hold = board.hold.map(|c| c.to_string());
        assert_eq!(got_hold, case.hold, "hold mismatch in case {}", case.name);
        assert_eq!(
            board.lines_cleared, case.lines_cleared,
            "lines in case {}",
            case.name
        );
        assert_eq!(
            board.pieces_placed, case.pieces_placed,
            "pieces in case {}",
            case.name
        );
    }
}
