"use strict";
var fs = require('fs');
var path = require('path');
var rules_1 = require('./rules');
function formatUsage(usage) {
    return usage.replace(/~~~/g, '```').replace(/(^[ \t]*\n)/gm, '\n').replace(/^    /mg, '');
}
exports.formatUsage = formatUsage;
function createRuleTable() {
    var buffer = [];
    var category = null;
    rules_1.rules.forEach(function (rule) {
        if (category !== rule.category) {
            category = rule.category;
            buffer.push("\n### " + category + "\n\n");
            buffer.push(rules_1.categories[category] + "\n\n");
            buffer.push('| :grey_question: | ESLint | TSLint | Description |\n');
            buffer.push('| :---            | :---:  | :---:  | :---        |\n');
        }
        var available;
        if (rule.available) {
            available = rule.provider === 'native' ? ':ballot_box_with_check:' : ':white_check_mark:';
        }
        else {
            available = rule.tslintRule === 'Not applicable' ? ':no_entry_sign:' : ':x:';
        }
        var tsRuleName = rule.tslintUrl ? "[" + rule.tslintRule + "](" + rule.tslintUrl + ")" : rule.tslintRule;
        var tsRule = rule.tslintRule === 'Not applicable' ? 'Not applicable' : tsRuleName;
        buffer.push('|');
        buffer.push(available + "|");
        buffer.push("[" + rule.eslintRule + "](" + rule.eslintUrl + ")|");
        buffer.push(tsRule + "|");
        buffer.push(rule.description + "|");
        buffer.push('\n');
    });
    return buffer.join('');
}
function updateReadme(cb) {
    fs.readFile('README.md', 'utf8', function (readErr, data) {
        if (readErr) {
            return console.error(readErr);
        }
        var content = data.replace(/^<!-- Start:AutoTable((.*?(\n))+.*?)End:AutoTable -->$/gm, '<!-- Start:AutoTable:: Modify `src/readme/rules.ts` and run `gulp readme` to update block -->\n' +
            createRuleTable() +
            '<!-- End:AutoTable -->');
        fs.writeFile('README.md', content, 'utf8', function (writeErr) {
            if (writeErr) {
                return console.error(writeErr);
            }
            console.log('[DONE] updating README.md ...');
            cb();
        });
    });
}
exports.updateReadme = updateReadme;
function createRuleContent(rule) {
    var usage = rule.usage ? "\n\n### Usage\n\n" + formatUsage(rule.usage) : '';
    var note = rule.note ? "\n\n### Note\n\n" + rule.note + "\n" : '';
    return "## " + rule.tslintRule + " (ESLint: [" + rule.eslintRule + "](" + rule.eslintUrl + "))\n\n" + rule.description + usage + note + "\n";
}
function updateRuleFile(name, rule) {
    var baseUrl = 'https://github.com/buzinas/tslint-eslint-rules/blob/master';
    var docFileName = "src/docs/rules/" + name + "Rule.md";
    return new Promise(function (fulfill, reject) {
        fs.readFile(docFileName, 'utf8', function (readErr, data) {
            rule.tslintUrl = rule.tslintUrl || baseUrl + "/" + docFileName;
            var content = readErr || !data ? '<!-- Start:AutoDoc\n End:AutoDoc -->' : data;
            content = content.replace(/^<!-- Start:AutoDoc((.*?(\n))+.*?)End:AutoDoc -->$/gm, [
                '<!-- Start:AutoDoc:: Modify `src/readme/rules.ts` and run `gulp readme` to update block -->\n',
                createRuleContent(rule),
                '\n<!-- End:AutoDoc -->' + (readErr ? '\n' : '')
            ].join(''));
            fs.writeFile(docFileName, content, 'utf8', function (writeErr) {
                if (writeErr) {
                    return reject(writeErr);
                }
                console.log(" - " + name);
                fulfill();
            });
        });
    });
}
function updateRuleFiles(cb) {
    var ruleDir = 'src/rules/';
    var allFiles = fs.readdirSync(ruleDir).filter(function (file) { return fs.lstatSync(path.join(ruleDir, file)).isFile(); });
    var ruleNames = allFiles
        .filter(function (name) { return name.endsWith('.ts'); })
        .map(function (name) { return name.substr(0, name.length - 7); });
    var allPromises = [];
    ruleNames.forEach(function (name) {
        allPromises.push(updateRuleFile(name, rules_1.ruleTSMap[name]));
    });
    Promise.all(allPromises).then(function () {
        console.log('[DONE] processing rule files ...');
        cb();
    });
}
exports.updateRuleFiles = updateRuleFiles;
