local utils = require "sudoku.utils"

local sudoku = {}

function sudoku.iterZones(board)
    local row = 0
    local column = 0
    local block = 0
    return function()
        local a = {}
        local p = {}
        if row < 9 then
            row = row + 1
            for i = 1, 9 do
                a[i] = board[row][i]
                p[i] = {row, i}
            end
            return a, p
        end
        if column < 9 then
            column = column + 1
            for i = 1, 9 do
                a[i] = board[i][column]
                p[i] = {i, column}
            end
            return a, p
        end
        if block < 9 then
            block = block + 1
            local dx = math.floor((block - 1) / 3)
            local dy = (block - 1) % 3
            local n = 0
            for i = 1, 3 do
                for j = 1, 3 do
                    local x = i + 3 * dx
                    local y = j + 3 * dy
                    n = n + 1
                    a[n] = board[x][y]
                    p[n] = {x, y}
                end
            end
            return a, p
        end
    end
end

local function checkAUX(zone, pos)
    local isComplete = true
    local ok = true
    local conflictList = {}
    local n = 0
    for i = 1, 8 do
        for j = i+1, 9 do
            if zone[i] == 0 then
                isComplete = false
            elseif zone[i] == zone[j] then
                ok = false
                n = n + 1
                conflictList[n] = {x1=pos[i][1], y1=pos[i][2], x2=pos[j][1], y2=pos[j][2]}
            end
        end
    end
    return ok, isComplete, conflictList
end

function sudoku.checkBoard(board)
    local ok = true
    local isComplete = true
    local conflictList = {}
    for zone, pos in sudoku.iterZones(board) do
        local tOk, tIsComplete, tConflictList = checkAUX(zone, pos)
        if not tOk then ok = false end
        if not tIsComplete then isComplete = false end
        for _, conflict in ipairs(tConflictList) do
            table.insert(conflictList, conflict)
        end
    end
    return ok, isComplete, conflictList
end

sudoku.cloneBoard = utils.cloneBoard
sudoku.createEmptyBoard = utils.createEmptyBoard
sudoku.loadBoard = utils.loadBoard
return sudoku