import { BaseXform } from "./base-xform.js";
class ListXform extends BaseXform {
    constructor(options) {
        super();
        this.tag = options.tag;
        this.always = !!options.always;
        this.count = options.count;
        this.empty = options.empty;
        this.$count = options.$count ?? "count";
        this.$ = options.$;
        this.childXform = options.childXform;
        this.maxItems = options.maxItems;
    }
    prepare(model, options) {
        const { childXform } = this;
        if (model) {
            model.forEach((childModel, index) => {
                options.index = index;
                childXform.prepare(childModel, options);
            });
        }
    }
    render(xmlStream, model) {
        if (this.always || (model && model.length)) {
            xmlStream.openNode(this.tag, this.$);
            if (this.count) {
                xmlStream.addAttribute(this.$count, model?.length ?? 0);
            }
            const { childXform } = this;
            (model ?? []).forEach((childModel, index) => {
                childXform.render(xmlStream, childModel, index);
            });
            xmlStream.closeNode();
        }
        else if (this.empty) {
            xmlStream.leafNode(this.tag);
        }
    }
    parseOpen(node) {
        if (this.parser) {
            this.parser.parseOpen(node);
            return true;
        }
        if (node.name === this.tag) {
            this.model = [];
            return true;
        }
        if (this.childXform.parseOpen(node)) {
            this.parser = this.childXform;
            return true;
        }
        return false;
    }
    parseText(text) {
        if (this.parser) {
            this.parser.parseText(text);
        }
    }
    parseClose(name) {
        if (this.parser) {
            if (!this.parser.parseClose(name)) {
                this.model.push(this.parser.model);
                this.parser = undefined;
                if (this.maxItems && this.model.length > this.maxItems) {
                    throw new Error(`Max ${this.childXform.tag} count (${this.maxItems}) exceeded`);
                }
            }
            return true;
        }
        return false;
    }
    reconcile(model, options) {
        if (model) {
            const { childXform } = this;
            model.forEach((childModel) => {
                childXform.reconcile(childModel, options);
            });
        }
    }
    reset() {
        super.reset();
        if (this.childXform) {
            this.childXform.reset();
        }
    }
}
export { ListXform };
