"use strict";

var path = require("path"),
    fs   = require("fs");

var gitSemverTags = require("git-semver-tags"),
    gitRawCommits = require("git-raw-commits"),
    minimist      = require("minimist");

var basedir = path.join(__dirname, "..");
var pkg = require(basedir + "/package.json");

var argv = minimist(process.argv, {
    alias: {
        tag    : "t",
        write  : "w"
    },
    string: [ "tag" ],
    boolean: [ "write" ],
    default: {
        tag: null,
        write: false
    }
});

// categories to be used in the future and regexes for lazy / older subjects
var validCategories = {
    "Breaking": null,
    "Fixed": /fix|properly|prevent|correctly/i,
    "New": /added|initial/i,
    "CLI": /pbjs|pbts|CLI/,
    "Docs": /README/i,
    "Other": null
};
var breakingFallback = /removed|stripped|dropped/i;

var repo = "https://github.com/protobufjs/protobuf.js";

gitSemverTags(function(err, tags) {
    if (err)
        throw err;

    var categories = {};
    Object.keys(validCategories).forEach(function(category) {
        categories[category] = [];
    });
    var output = [];

    var from = tags[0];
    var to = "HEAD";
    var tag;
    if (argv.tag) {
        var idx = tags.indexOf(argv.tag);
        if (idx < 0)
            throw Error("no such tag: " + argv.tag);
        from = tags[idx + 1];
        tag = to = tags[idx];
    } else
        tag = pkg.version;

    var commits = gitRawCommits({
        from: from,
        to: to,
        merges: false,
        format: "%B%n#%H"
    });

    commits.on("error", function(err) {
        throw err;
    });

    commits.on("data", function(chunk) {
        var message = chunk.toString("utf8").trim();
        var match = /##([0-9a-f]{40})$/.exec(message);
        var hash;
        if (match) {
            message = message.substring(0, message.length - match[1].length).trim();
            hash = match[1];
        }
        message.split(";").forEach(function(message) {
            if (/^(Merge pull request |Post-merge)/.test(message))
                return;
            var match = /^(\w+):/i.exec(message = message.trim());
            var category;
            if (match && match[1] in validCategories) {
                category = match[1];
                message = message.substring(match[1].length + 1).trim();
            } else {
                var keys = Object.keys(validCategories);
                for (var i = 0; i < keys.length; ++i) {
                    var re = validCategories[keys[i]];
                    if (re && re.test(message)) {
                        category = keys[i];
                        break;
                    }
                }
                message = message.replace(/^(\w+):/i, "").trim();
            }
            if (!category) {
                if (breakingFallback.test(message))
                    category = "Breaking";
                else
                    category = "Other";
            }
            var nl = message.indexOf("\n");
            if (nl > -1)
                message = message.substring(0, nl).trim();
            if (!hash || message.length < 12)
                return;
            message = message.replace(/\[ci skip\]/, "").trim();
            categories[category].push({
                text: message,
                hash: hash
            });
        });
    });

    commits.on("end", function() {
        output.push("## [" + tag + "](" + repo + "/releases/tag/" + tag + ")\n");
        Object.keys(categories).forEach(function(category) {
            var messages = categories[category];
            if (!messages.length)
                return;
            output.push("\n### " + category + "\n");
            messages.forEach(function(message) {
                var text = message.text.replace(/#(\d+)/g, "[#$1](" + repo + "/issues/$1)");
                output.push("[:hash:](" + repo + "/commit/" + message.hash + ") " + text + "<br />\n");
            });
        });
        var current;
        try {
            current = fs.readFileSync(basedir + "/CHANGELOG.md").toString("utf8");
        } catch (e) {
            current = "";
        }
        var re = new RegExp("^## \\[" + tag + "\\]");
        if (re.test(current)) { // regenerated, replace
            var pos = current.indexOf("## [", 1);
            if (pos > -1)
                current = current.substring(pos).trim();
            else
                current = "";
        }
        var contents = output.join("") + "\n" + current;
        if (argv.write)
            fs.writeFileSync(basedir + "/CHANGELOG.md", contents, "utf8");
        else
            process.stdout.write(contents);
    });
});
