// deno-fmt-ignore
const charVal: {[key: string]: number} = {
    "0": 0, "1": 1, "2": 2, "3": 3,
    "4": 4, "5": 5, "6": 6, "7": 7,
    "8": 8, "9": 9, "a": 10, "b": 11,
    "c": 12, "d": 13, "e": 14, "f": 15,
};
const base2Digits = ["0", "1"];
const base8Digits = [...base2Digits, "2", "3", "4", "5", "6", "7"];
const base10Digits = [...base8Digits, "8", "9"];
const base16Digits = [...base10Digits, "a", "b", "c", "d", "e", "f"];

export function stringToInt(text: string): number {
    if (text.length === 0) {
        return NaN;
    }
    if (text[0] === "0") {
        if (text.length === 1) {
            return 0;
        } else if (text[1] == "b") {
            return parseDigits(text.slice(2), 2, base2Digits);
        } else if (text[1] == "x") {
            return parseDigits(text.slice(2), 16, base16Digits);
        } else {
            return parseDigits(text.slice(1), 8, base8Digits);
        }
    }
    return parseDigits(text, 10, base10Digits);
}

function parseDigits(
    numberText: string,
    base: number,
    digitSet: string[],
): number {
    let value = 0;
    for (const ch of numberText) {
        value *= base;
        if (!digitSet.includes(ch)) {
            return NaN;
        }
        value += charVal[ch];
    }
    return value;
}