/**
 * @import { Radix } from "./num.js"
 */
import { S16_0, S16_1, S16_2, S16_3, S16_4, S16_5, S16_6, S16_7, S16_8, S16_9, S16_A, S16_B, S16_C, S16_D, S16_E, S16_F } from "./symbol/S16.js"
import { S8_0, S8_1, S8_2, S8_3, S8_4, S8_5, S8_6, S8_7 } from "./symbol/S8.js"
import { S2_0, S2_1 } from "./symbol/S2.js"
import { S10_0, S10_1, S10_2, S10_3, S10_4, S10_5, S10_6, S10_7, S10_8, S10_9 } from "./symbol/S10.js"
import { __throw } from "./utils.js";

/**
 * @param { string } char 
 */
function parse16B(char) {
    switch (char) {
        case "0": return S16_0;
        case "1": return S16_1;
        case "2": return S16_2;
        case "3": return S16_3;
        case "4": return S16_4;
        case "5": return S16_5;
        case "6": return S16_6;
        case "7": return S16_7;
        case "8": return S16_8;
        case "9": return S16_9;
        case "a": return S16_A;
        case "A": return S16_A;
        case "b": return S16_B;
        case "B": return S16_B;
        case "c": return S16_C;
        case "C": return S16_C;
        case "d": return S16_D;
        case "D": return S16_D;
        case "e": return S16_E;
        case "E": return S16_E;
        case "f": return S16_F;
        case "F": return S16_F;
        default: throw new Error(`unexpected symbol (${char})`)
    }
}

/**
 * @param { string } char 
 */
function parse8B(char) {
    switch (char) {
        case "0": return S8_0;
        case "1": return S8_1;
        case "2": return S8_2;
        case "3": return S8_3;
        case "4": return S8_4;
        case "5": return S8_5;
        case "6": return S8_6;
        case "7": return S8_7;
        default: throw new Error(`unexpected symbol (${char})`)
    }
}

/**
 * @param { string } char 
 */
function parse2B(char) {
    switch (char) {
        case "0": return S2_0;
        case "1": return S2_1;
        default: throw new Error(`unexpected symbol (${char})`)
    }
}

/**
 * @param { string } char 
 */
function parse10B(char) {
    switch (char) {
        case "0": return S10_0;
        case "1": return S10_1;
        case "2": return S10_2;
        case "3": return S10_3;
        case "4": return S10_4;
        case "5": return S10_5;
        case "6": return S10_6;
        case "7": return S10_7;
        case "8": return S10_8;
        case "9": return S10_9;
        default: throw new Error(`unexpected symbol (${char})`)
    }
}

/**
 * @param { string } value 
 * @param { symbol[] } buffer 
 */
function parse16(value, buffer) {
    for (let i = 0, j = value.length - 1; i < buffer.length && j >= 0; i++, j--) {
        buffer[i] = parse16B(value[j]);   
    }
}

/**
 * @param { string } value 
 * @param { symbol[] } buffer 
 */
function parse8(value, buffer) {
    for (let i = 0, j = value.length - 1; i < buffer.length && j >= 0; i++, j--) {
        buffer[i] = parse8B(value[j]);
    }
}

/**
 * @param { string } value 
 * @param { symbol[] } buffer 
 */
function parse2(value, buffer) {
    for (let i = 0, j = value.length - 1; i < buffer.length && j >= 0; i++, j--) {
        buffer[i] = parse2B(value[j]);
    }
}

/**
 * @param { string } value 
 * @param { symbol[] } buffer 
 */
function parse10(value, buffer) {
    for (let i = 0, j = value.length - 1; i < buffer.length && j >= 0; i++, j--) {
        buffer[i] = parse10B(value[j]);
    }
}

/**
 * @param { Radix } radix 
 * @param { string } value 
 * @param { symbol[] } buffer 
 */
export function parse(radix, value, buffer) {
    switch (radix) {
        case 2: return parse2(value, buffer);
        case 8: return parse8(value, buffer);
        case 16: return parse16(value, buffer);
        case 10: return parse10(value, buffer);
        default: throw new Error(`unsupported radix (${radix})`);
    }
}