package sudoku.solver;

import java.util.List;
import java.util.logging.Logger;

import sudoku.structure.Cell;
import sudoku.structure.MultiDoku;

public interface Solver {

    /**
     * Log du Solver, qui garde trace des actions réalisées.
     */
    public static final Logger logger = Logger.getLogger("SolverLogger");

    boolean solve(MultiDoku doku, List<SolverStep> solverSteps);

    default boolean solve(MultiDoku doku) {
        return solve(doku, null);
    }

    /**
     * Compte le nombre de solutions possibles au MultiDoku passé en paramètres.
     *
     * @param doku MultiDoku, MultiDoku dont on veut le nombre de solutions.
     * @return int, nombre de solutions possibles.
     */
    default int countSolution(MultiDoku doku) {
        int result = 0;

        if (doku.isSolved()) {
            return 1;
        }

        Cell cellToFill = doku.getFirstEmptyCell();
        assert (cellToFill != null);

        List<Integer> possibleSymbols = cellToFill.getPossibleSymbols();

        for (int symbol : possibleSymbols) {
            doku.getStateManager().pushState();
            cellToFill.setSymbolIndex(symbol);
            if (solve(doku)) {
                result++;
                if (result > 1) {
                    doku.getStateManager().popState();
                    return result;
                }
            }
            doku.getStateManager().popState();
        }
        return result;
    }

    default void addStep(Cell cell, List<SolverStep> steps) {
        if (steps == null)
            return;
        steps.add(new SolverStep(cell));
    }

}
