"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const createShiftArr = step => {
    let space = '    ';
    if (isNaN(parseInt(step, 10))) {
        // argument is string
        space = step;
    }
    else {
        // argument is integer
        space = new Array(step + 1).join(' '); // space is result of join (a string), not an array
    }
    const shift = ['\n']; // array of shifts
    for (let ix = 0; ix < 100; ix += 1) {
        shift.push(shift[ix] + space);
    }
    return shift;
};
let shift = createShiftArr('    ');
const formatXml = text => {
    if (!shift) {
        shift = createShiftArr('    ');
    }
    const ar = text
        .replace(/>\s{0,}</g, '><')
        .replace(/</g, '~::~<')
        .replace(/\s*xmlns\:/g, '~::~xmlns:')
        .replace(/\s*xmlns\=/g, '~::~xmlns=')
        .split('~::~');
    const len = ar.length;
    let inComment = false;
    let deep = 0;
    let str = '';
    let ix = 0;
    for (ix = 0; ix < len; ix += 1) {
        // start comment or <![CDATA[...]]> or <!DOCTYPE //
        if (ar[ix].search(/<!/) > -1) {
            str += shift[deep] + ar[ix];
            inComment = true;
            // end comment  or <![CDATA[...]]> //
            if (ar[ix].search(/-->/) > -1 ||
                ar[ix].search(/\]>/) > -1 ||
                ar[ix].search(/!DOCTYPE/) > -1) {
                inComment = false;
            }
        }
        else if (ar[ix].search(/-->/) > -1 || ar[ix].search(/\]>/) > -1) {
            // end comment  or <![CDATA[...]]> //
            str += ar[ix];
            inComment = false;
        }
        else if (/^<\w/.exec(ar[ix - 1]) &&
            /^<\/\w/.exec(ar[ix]) &&
            /^<[\w:\-\.\,]+/.exec(ar[ix - 1]) ===
                /^<\/[\w:\-\.\,]+/.exec(ar[ix])[0].replace('/', '')) {
            // <elm></elm> //
            str += ar[ix];
            if (!inComment)
                deep -= 1;
        }
        else if (ar[ix].search(/<\w/) > -1 &&
            ar[ix].search(/<\//) === -1 &&
            ar[ix].search(/\/>/) === -1) {
            // <elm> //
            str = !inComment ? (str += shift[deep] + ar[ix]) : (str += ar[ix]);
            deep += 1;
        }
        else if (ar[ix].search(/<\w/) > -1 && ar[ix].search(/<\//) > -1) {
            // <elm>...</elm> //
            str = !inComment ? (str += shift[deep] + ar[ix]) : (str += ar[ix]);
        }
        else if (ar[ix].search(/<\//) > -1) {
            deep -= 1;
            // </elm> //
            str = !inComment ? (str += shift[deep] + ar[ix]) : (str += ar[ix]);
        }
        else if (ar[ix].search(/\/>/) > -1) {
            // <elm/> //
            str = !inComment ? (str += shift[deep] + ar[ix]) : (str += ar[ix]);
        }
        else if (ar[ix].search(/<\?/) > -1) {
            // <? xml ... ?> //
            str += shift[deep] + ar[ix];
        }
        else if (ar[ix].search(/xmlns\:/) > -1 || ar[ix].search(/xmlns\=/) > -1) {
            // xmlns //
            str += shift[deep] + ar[ix];
        }
        else {
            str += ar[ix];
        }
    }
    return str[0] === '\n' ? str.slice(1) : str;
};
exports.default = formatXml;
