"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MDGator = exports.Test = exports.Group = void 0;
const Markdown = require("markdown-it");
const group_1 = require("./group");
Object.defineProperty(exports, "Group", { enumerable: true, get: function () { return group_1.Group; } });
const test_1 = require("./test");
Object.defineProperty(exports, "Test", { enumerable: true, get: function () { return test_1.Test; } });
class MDGator {
    constructor() {
        this.md = new Markdown({ html: true });
        this.state = 'none';
    }
    parse(text) {
        const tokens = this.md.parse(text, {});
        const roots = [];
        let metadata;
        let depth;
        const stack = [];
        for (const token of tokens) {
            const type = token.type;
            if (type === 'heading_open') {
                this.state = 'heading';
                metadata = undefined;
                // Leave previous headings
                depth = parseInt(token.tag.slice(1), 10) - 1;
                while (stack.length !== 0 && stack[stack.length - 1].depth >= depth) {
                    stack.pop();
                }
            }
            else if (type === 'heading_close') {
                this.state = 'none';
                metadata = undefined;
            }
            else if (type === 'inline') {
                if (this.state !== 'heading') {
                    continue;
                }
                const heading = {
                    children: [],
                    content: new Map(),
                    depth: depth,
                    line: token.map[0],
                    meta: new Map(),
                    name: token.content,
                };
                depth = undefined;
                if (stack.length === 0) {
                    roots.push(heading);
                }
                else {
                    stack[stack.length - 1].children.push(heading);
                }
                stack.push(heading);
            }
            else if (type === 'fence' && stack.length > 1) {
                const current = stack[stack.length - 1];
                if (!current.content.has(token.info)) {
                    current.content.set(token.info, []);
                }
                current.content.get(token.info).push(token.content);
                // Set metadata
                if (metadata !== undefined) {
                    if (!current.meta.has(token.info)) {
                        current.meta.set(token.info, []);
                    }
                    current.meta.get(token.info).push(metadata);
                    metadata = undefined;
                }
            }
            else if (type === 'html_block' && stack.length >= 1) {
                const match = token.content.match(/<!--\s+meta=(.*)\s+-->/);
                if (match === null) {
                    continue;
                }
                let json;
                try {
                    json = JSON.parse(match[1]);
                }
                catch (e) {
                    throw new Error(`Failed to parse JSON metadata: "${match[1]}"`);
                }
                metadata = json;
            }
        }
        return roots.map((root) => this.translate(root));
    }
    translate(heading) {
        const children = heading.children.filter((child) => {
            return child.children.length !== 0;
        }).map((child) => this.translate(child));
        const tests = heading.children.filter((child) => {
            return child.content.size !== 0;
        }).map((child) => this.translateTest(child));
        return new group_1.Group(heading.name, heading.line, children, tests);
    }
    translateTest(heading) {
        return new test_1.Test(heading.name, heading.line, heading.content, heading.meta);
    }
}
exports.MDGator = MDGator;
//# sourceMappingURL=mdgator.js.map