import { EventIterator } from 'event-iterator';
import { instance as banPatternInstance } from '../../rules/banPatternRule.js';
import { instance as cellCountInstance } from '../../rules/cellCountRule.js';
import { instance as regionAreaInstance } from '../../rules/regionAreaRule.js';
import { instance as sameShapeInstance } from '../../rules/sameShapeRule.js';
import { instance as symbolsPerRegionInstance } from '../../rules/symbolsPerRegionRule.js';
import { instance as undercluedInstance } from '../../rules/undercluedRule.js';
import { instance as uniqueShapeInstance } from '../../rules/uniqueShapeRule.js';
import { Serializer } from '../../serializer/allSerializers.js';
import { instance as areaNumberInstance } from '../../symbols/areaNumberSymbol.js';
import { instance as dartInstance } from '../../symbols/dartSymbol.js';
import { instance as galaxyInstance } from '../../symbols/galaxySymbol.js';
import { instance as letterInstance } from '../../symbols/letterSymbol.js';
import { instance as lotusInstance } from '../../symbols/lotusSymbol.js';
import { instance as minesweeperInstance } from '../../symbols/minesweeperSymbol.js';
import { instance as myopiaInstance } from '../../symbols/myopiaSymbol.js';
import { instance as viewpointInstance } from '../../symbols/viewpointSymbol.js';
import Solver from '../solver.js';
import { instance as connectAllInstance } from '../z3/modules/connectAllModule.js';
class BacktrackSolver extends Solver {
    constructor() {
        super(...arguments);
        Object.defineProperty(this, "id", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: 'backtrack'
        });
        Object.defineProperty(this, "description", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: 'Solves puzzles using backtracking with optimizations (blazingly fast). Support most rules and symbols (including underclued).'
        });
    }
    async *solve(grid) {
        const worker = new Worker(new URL('./backtrackWorker.js', import.meta.url), {
            type: 'module',
        });
        try {
            const iterator = new EventIterator(({ push, stop, fail }) => {
                worker.postMessage(Serializer.stringifyGrid(grid.resetTiles()));
                worker.addEventListener('message', (e) => {
                    if (e.data) {
                        push(Serializer.parseGrid(e.data));
                    }
                    else {
                        stop();
                    }
                });
                worker.addEventListener('error', (e) => {
                    alert(`Error while solving!\n${e.message}`);
                    fail(new Error(e.message));
                });
            });
            for await (const solution of iterator) {
                yield solution;
            }
            yield null;
        }
        finally {
            worker.terminate();
        }
    }
    isInstructionSupported(instructionId) {
        return BacktrackSolver.supportedInstrs.includes(instructionId);
    }
}
Object.defineProperty(BacktrackSolver, "supportedInstrs", {
    enumerable: true,
    configurable: true,
    writable: true,
    value: [
        areaNumberInstance.id,
        viewpointInstance.id,
        dartInstance.id,
        galaxyInstance.id,
        lotusInstance.id,
        myopiaInstance.id,
        minesweeperInstance.id,
        letterInstance.id,
        undercluedInstance.id,
        connectAllInstance.id,
        banPatternInstance.id,
        regionAreaInstance.id,
        symbolsPerRegionInstance.id,
        cellCountInstance.id,
        sameShapeInstance.id,
        uniqueShapeInstance.id,
    ]
});
export default BacktrackSolver;
