// Swipe→commit wiring golden (P5.2): prove the full input-to-model path P5.2
// adds — a touch drag resolved by `swipe_intent` and fed straight into
// `commit_swap` — on the SAME seeded board the iOS app renders (SEED 1337).
// Feeds SYNTHETIC down/up screen positions built from a BoardLayout, resolves
// the swap intent, then commits it, asserting:
//   - an ILLEGAL swipe ((0,0)->(1,0): two reds → no match) reverts: the board is
//     byte-for-byte unchanged, score stays 0, and no move is spent;
//   - a known LEGAL swipe ((5,4)->(6,4): brings R into (5,4), completing R,R,R
//     across cols 3-5 of row 4) commits: the board changes, score accrues, and
//     exactly one move is spent.
// No rendering, no model reach-around — it calls exactly what BoardView.handle_event
// calls. Links headless like tests/swipe_intent.sx; avoids tests/test.sx because
// its trace.sx pulls in a second `Frame` that collides with the UI one. Failure
// is signalled via a non-zero exit code (the runner checks exit code AND stdout).
#import "modules/std.sx";
#import "board.sx";
#import "board_layout.sx";
#import "swipe.sx";

SEED :: 1337;

cell_center :: (lay: *BoardLayout, col: s64, row: s64) -> Point {
    cf := lay.cell_frame(col, row);
    Point.{ x = cf.mid_x(), y = cf.mid_y() }
}

boards_equal :: (x: *Board, y: *Board) -> bool {
    for 0..BOARD_CELLS: (i) {
        if !(x.cells[i] == y.cells[i]) { return false; }
    }
    true
}

main :: () -> s32 {
    // 800×600, no safe inset → 600px square grid, cell 75, origin (100, 0). A
    // 60px drag clears the cell*0.5 = 37.5px swipe threshold on the dominant axis.
    lay : BoardLayout = ---;
    lay.compute(Frame.make(0.0, 0.0, 800.0, 600.0), EdgeInsets.zero());
    D : f32 = 60.0;

    fails : s64 = 0;

    // ── ILLEGAL swipe reverts ──────────────────────────────────────────────
    // (0,0) and (1,0) are both red on the seed board, so swapping them forms no
    // match. The rightward drag must resolve to exactly this pair, and
    // commit_swap must reject it — board untouched, score 0, no move spent.
    print("== illegal swipe reverts ==\n");
    bi : Board = ---;
    bi.init(SEED);
    before : Board = bi;
    out(board_dump(@bi));

    a_il := cell_center(@lay, 0, 0);
    if s := swipe_intent(@lay, a_il, Point.{ x = a_il.x + D, y = a_il.y }) {
        print("intent ({},{})->({},{})\n", s.a.col, s.a.row, s.b.col, s.b.row);
        if !(s.a.col == 0 and s.a.row == 0 and s.b.col == 1 and s.b.row == 0) { fails += 1; }
        mv := commit_swap(@bi, s.a, s.b);
        print("legal {} awarded {} score {} moves_made {} moves_remaining {}\n",
              mv.legal, mv.cascade.awarded, bi.score, bi.moves_made, mv.moves_remaining);
        if mv.legal { fails += 1; }
        if !boards_equal(@before, @bi) { fails += 1; }
        if bi.score != 0 { fails += 1; }
        if bi.moves_made != 0 { fails += 1; }
        if mv.moves_remaining != bi.move_limit { fails += 1; }
    } else {
        print("intent none\n");
        fails += 1;
    }

    // ── LEGAL swipe commits ────────────────────────────────────────────────
    // (5,4)->(6,4): the rightward swipe brings R into (5,4), completing R,R,R
    // across cols 3-5 of row 4. commit_swap applies it, resolves the cascade
    // (score accrues into Board.score) and spends one move; the board changes.
    print("== legal swipe commits ==\n");
    bl : Board = ---;
    bl.init(SEED);
    pre : Board = bl;

    a_le := cell_center(@lay, 5, 4);
    if s := swipe_intent(@lay, a_le, Point.{ x = a_le.x + D, y = a_le.y }) {
        print("intent ({},{})->({},{})\n", s.a.col, s.a.row, s.b.col, s.b.row);
        if !(s.a.col == 5 and s.a.row == 4 and s.b.col == 6 and s.b.row == 4) { fails += 1; }
        mv := commit_swap(@bl, s.a, s.b);
        print("legal {} depth {} awarded {} score {} moves_made {} moves_remaining {}\n",
              mv.legal, mv.cascade.depth, mv.cascade.awarded, bl.score, bl.moves_made, mv.moves_remaining);
        if !mv.legal { fails += 1; }
        if boards_equal(@pre, @bl) { fails += 1; }
        if !(bl.score > 0) { fails += 1; }
        if bl.moves_made != 1 { fails += 1; }
        if mv.moves_remaining != bl.move_limit - 1 { fails += 1; }
        out("after:\n");
        out(board_dump(@bl));
    } else {
        print("intent none\n");
        fails += 1;
    }

    if fails == 0 {
        print("ok: swipe reverts illegal, commits legal\n");
        return 0;
    }
    print("FAIL: {} swipe-commit checks failed\n", fails);
    return 1;
}
