import SerializerV0 from './serializer_v0.js';
const allSerializers = new Map();
function register(prototype) {
    allSerializers.set(prototype.version, prototype);
}
let defaultSerializer;
register((defaultSerializer = new SerializerV0()));
function selectSerializer(input) {
    const match = input.match(/^(\d+)_/);
    const version = match ? parseInt(match[1]) : 0;
    const serializer = allSerializers.get(version);
    if (serializer) {
        return { serializer, data: input.slice(match?.[0].length ?? 0) };
    }
    else {
        throw new Error(`Unknown serializer version for ${input}`);
    }
}
/**
 * The master serializer for puzzles.
 *
 * It uses the default serializer when stringifying puzzles, and select the correct deserializer when parsing puzzles.
 */
const Serializer = {
    stringifyRule(rule) {
        return `${defaultSerializer.version}_${defaultSerializer.stringifyRule(rule)}`;
    },
    parseRule(input) {
        const { serializer, data } = selectSerializer(input);
        return serializer.parseRule(data);
    },
    stringifySymbol(symbol) {
        return `${defaultSerializer.version}_${defaultSerializer.stringifySymbol(symbol)}`;
    },
    parseSymbol(input) {
        const { serializer, data } = selectSerializer(input);
        return serializer.parseSymbol(data);
    },
    stringifyGrid(grid) {
        return `${defaultSerializer.version}_${defaultSerializer.stringifyGrid(grid)}`;
    },
    parseGrid(input) {
        const { serializer, data } = selectSerializer(input);
        return serializer.parseGrid(data);
    },
    /**
     * Convert a puzzle to a string.
     * @param puzzle The puzzle to convert.
     * @returns The string representation of the puzzle.
     */
    stringifyPuzzle(puzzle) {
        return `${defaultSerializer.version}_${defaultSerializer.stringifyPuzzle(puzzle)}`;
    },
    /**
     * Parse a puzzle from a string.
     * @param input The string to parse.
     * @returns The parsed puzzle.
     */
    parsePuzzle(input) {
        const { serializer, data } = selectSerializer(input);
        return serializer.parsePuzzle(data);
    },
};
export { Serializer };
