// SPDX-License-Identifier: Apache-2.0
import { IllegalArgumentError } from '../../../business/errors/illegal-argument-error.js';
import { LexerLeafNode } from './lexer-leaf-node.js';
import { ReflectAssist } from '../../../business/utils/reflect-assist.js';
import { ConfigKeyError } from '../config-key-error.js';
import { LexerNode } from './lexer-node.js';
import { ConfigKeyFormatter } from '../config-key-formatter.js';
export class LexerInternalNode extends LexerNode {
    array;
    arrayIndex;
    _children = new Map();
    constructor(parent, name, children, array = false, arrayIndex = false, formatter = ConfigKeyFormatter.instance()) {
        super(parent, name, formatter);
        this.array = array;
        this.arrayIndex = arrayIndex;
        if (children) {
            for (const c of children) {
                if (c instanceof LexerInternalNode && c.isRoot()) {
                    throw new ConfigKeyError('Internal nodes cannot have root nodes as children');
                }
                this._children.set(c.name, c);
            }
        }
    }
    add(child) {
        if (!child) {
            throw new IllegalArgumentError('child must not be null or undefined');
        }
        if (!this._children.has(child.name)) {
            this._children.set(child.name, child);
        }
    }
    remove(child) {
        if (!child) {
            throw new IllegalArgumentError('child must not be null or undefined');
        }
        if (!this._children.has(child.name)) {
            throw new ConfigKeyError('Child not found');
        }
        this._children.delete(child.name);
    }
    clear() {
        this._children.clear();
    }
    replaceValue(child, value) {
        if (!child) {
            throw new IllegalArgumentError('child must not be null or undefined');
        }
        if (!this._children.has(child.name)) {
            throw new ConfigKeyError('Child not found');
        }
        if (!child.isLeaf()) {
            throw new ConfigKeyError('Child must be a leaf node');
        }
        const newLeaf = new LexerLeafNode(this, child.name, value, this.formatter);
        this._children.set(child.name, newLeaf);
    }
    get children() {
        return [...this._children.values()];
    }
    isRoot() {
        return this.parent === null || this.parent === undefined;
    }
    isInternal() {
        return true;
    }
    isLeaf() {
        return false;
    }
    isArray() {
        return this.array;
    }
    isArrayIndex() {
        return this.arrayIndex;
    }
    toObject() {
        const object = this.isArray() ? [] : {};
        for (const child of this.children) {
            if (this.isArray()) {
                if (!child.isArrayIndex()) {
                    throw new ConfigKeyError('Array node must have array index children');
                }
                const index = Number.parseInt(child.name);
                if (!Number.isSafeInteger(index)) {
                    throw new ConfigKeyError('Array index must be a number');
                }
                object[index] = child.toObject();
            }
            else {
                object[child.name] = child.isLeaf()
                    ? ReflectAssist.coerce(child.value)
                    : child.toObject();
            }
        }
        return object;
    }
}
//# sourceMappingURL=lexer-internal-node.js.map