-- HousingDecorGuide/tests/test_auto_layout.lua
---@diagnostic disable: undefined-global
-- ^ Standalone Lua test file — `package` / `require` / `dofile` are valid here even though
-- the project's WoW-context .luarc.json disables them.
package.path = "./?.lua;../Core/?.lua;" .. package.path

local AL = dofile("../Core/HDG_AutoLayout.lua")
local t = require("test_helpers")

-- Helper: produce a {shape, fingerprint} input for a room with the given occupied doors
local function room(shape, occupiedDoors)
    return {
        shape = shape,
        fingerprint = {
            degree = #occupiedDoors,
            doors = occupiedDoors,
            occupiedDoors = occupiedDoors,
        },
    }
end

t.describe("HDG_AutoLayout.compute", function()
    t.it("places a single isolated room at origin", function()
        local rooms = { ["r1"] = room("octagon_m", {}) }
        local result = AL.compute(rooms)
        t.assert_table_eq(result.layout["r1"].cell, { x = 0, y = 0 })
        t.assert_eq(#result.connections, 0)
    end)

    t.it("hub + 1 leaf to the east", function()
        local rooms = {
            ["r1"] = room("octagon_m", {"E"}),
            ["r2"] = room("closet_xs", {"W"}),
        }
        local result = AL.compute(rooms)
        -- Hub (degree 1, lower roomID) wins seed via alphabetical tie-break
        t.assert_table_eq(result.layout["r1"].cell, { x = 0, y = 0 })
        t.assert_table_eq(result.layout["r2"].cell, { x = 1, y = 0 })
        t.assert_eq(#result.connections, 1)
        t.assert_eq(result.connections[1].fromID, "r1")
        t.assert_eq(result.connections[1].toID, "r2")
        t.assert_eq(result.connections[1].fromDir, "E")
        t.assert_eq(result.connections[1].toDir, "W")
    end)

    t.it("hub with 4 cardinal leaves", function()
        local rooms = {
            ["hub"] = room("cross_shape", {"N","E","S","W"}),
            ["n"]   = room("closet_xs",   {"S"}),
            ["e"]   = room("closet_xs",   {"W"}),
            ["s"]   = room("closet_xs",   {"N"}),
            ["w"]   = room("closet_xs",   {"E"}),
        }
        local result = AL.compute(rooms)
        t.assert_table_eq(result.layout["hub"].cell, { x = 0,  y = 0 })
        t.assert_table_eq(result.layout["n"].cell,   { x = 0,  y = -1 })
        t.assert_table_eq(result.layout["e"].cell,   { x = 1,  y = 0 })
        t.assert_table_eq(result.layout["s"].cell,   { x = 0,  y = 1 })
        t.assert_table_eq(result.layout["w"].cell,   { x = -1, y = 0 })
        t.assert_eq(#result.connections, 4)
    end)

    t.it("two hubs connected by a chain of closets", function()
        -- Under lowest-degree-first heuristic: c1 wins seed (deg 2, alphabetical); c1
        -- connects N→hub1 and S→hub2 (both deg 1, preferred over c2 deg 2). c2 is placed
        -- as an isolated second component. Result: 4 placed, 2 connections.
        local rooms = {
            ["hub1"] = room("octagon_m",   {"S"}),
            ["c1"]   = room("closet_xs",   {"N","S"}),
            ["c2"]   = room("closet_xs",   {"N","S"}),
            ["hub2"] = room("cross_shape", {"N"}),
        }
        local result = AL.compute(rooms)
        local placed = 0
        for _ in pairs(result.layout) do placed = placed + 1 end
        t.assert_eq(placed, 4)
        t.assert_eq(#result.connections, 2)
    end)

    t.it("isolated rooms (no connections) all get placed without overlap", function()
        local rooms = {
            ["a"] = room("closet_xs", {}),
            ["b"] = room("closet_xs", {}),
            ["c"] = room("closet_xs", {}),
        }
        local result = AL.compute(rooms)
        local placed = 0
        for _ in pairs(result.layout) do placed = placed + 1 end
        t.assert_eq(placed, 3)
        local seen = {}
        for _, info in pairs(result.layout) do
            local key = info.cell.x .. "," .. info.cell.y
            t.assert_falsy(seen[key], "duplicate cell " .. tostring(key))
            seen[key] = true
        end
    end)

    t.it("empty input returns empty layout", function()
        local result = AL.compute({})
        t.assert_eq(next(result.layout), nil)
        t.assert_eq(#result.connections, 0)
    end)
end)

t.run_all()
