// ==UserScript==
// @name           Link to Mercurial Changesets
// @namespace      http://wiki.netbeans.org/BrowserTools
// @description    Turns Mercurial changesets in issue descriptions into links to http://hg.netbeans.org.
// @include        http*://*netbeans.org/*bugzilla/show_bug.cgi?id=*
// ==/UserScript==

// To test the script, use:
// - simple changeset: 
//   http://www.netbeans.org/nonav/bugzilla/show_bug.cgi?id=143037#c6
// - changeset preceded by hash:
//   http://www.netbeans.org/nonav/bugzilla/show_bug.cgi?id=143308#c3
// - changeset preceded by repo name:
//   http://www.netbeans.org/nonav/bugzilla/show_bug.cgi?id=138273#c16
// - changeset preceded by non-repo name:
//   http://www.netbeans.org/nonav/bugzilla/show_bug.cgi?id=144863#c2

function get_repo_path(repo) {
    if (repo == 'contrib') {
        return 'main/contrib';
    } else if (repo == 'misc') {
        return 'main/misc';
    } else if (repo == 'in' || repo == 'of' || repo == 'from' || repo == 'to') {
        return 'main-silver'; // not a real repo name
    } else if (!repo) {
        return 'main-silver'; // fallback
    } else {
        return repo;
    }
}

var regex = /([\w\/-]*)( +| *[#:]|^)([0-9a-f]{12})/gim;

// repo, prefix, and changeset correspond to the subgroups of the regex above.
function replacer(match, repo, prefix, changeset, offset, str) {
    // Build numbers are 12 digits, so they would be replaced here.
    // So only considering it a changeset if it contains at least one hexadecimal digit.
    if (!changeset.match(/[a-f]/i)) {
        return match;
    }
    var repo_path = get_repo_path(repo);
    return repo + prefix + '<a href="http://hg.netbeans.org/' + repo_path + '/rev/' + changeset + '">' + changeset + '</a>';
}

var nodes = document.evaluate('//div[@class="bz_comment"]/pre', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
for (var i = 0; i < nodes.snapshotLength; i++) {
    var node = nodes.snapshotItem(i);
    var text = node.innerHTML;
    text = text.replace(regex, replacer);
    node.innerHTML = text;
}
