/*
 Licensed to the Apache Software Foundation (ASF) under one
 or more contributor license agreements.  See the NOTICE file
 distributed with this work for additional information
 regarding copyright ownership.  The ASF licenses this file
 to you under the Apache License, Version 2.0 (the
 "License"); you may not use this file except in compliance
 with the License.  You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing,
 software distributed under the License is distributed on an
 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
 */

var fs = require('fs');
var path = require('path');
var stream = require('stream');
var optimist = require('optimist');
var executil = require('./executil');
var flagutil = require('./flagutil');
var gitutil = require('./gitutil');
var repoutil = require('./repoutil');
var linkify = require('jira-linkify');
var co_stream = require('co-stream');

var relNotesFile = 'RELEASENOTES.md';

module.exports = function*() {
    var meEmail = yield executil.execHelper(executil.ARGS('git config user.email'), true);
    var opt = flagutil.registerRepoFlag(optimist);
    opt = flagutil.registerHelpFlag(opt)
        .usage('Updates release notes with commits since the most recent tag.\n' +
        '\n' +
        'Usage: $0 update-release-notes [--repo=ios]'
        )
        .options('from-tag', {desc: 'Update since a specific tag instead of the "most recent" tag'})
        .options('to-tag', {desc: 'Update to a specific tag instead of "master"'})
        .options('override-date', {desc: 'Update to a specific date instead of today.'})
        .options('last-two-tags', {desc: 'Update with the latest and previous tagged commits'});
    argv = opt.argv;

    if (argv.h) {
        optimist.showHelp();
        process.exit(1);
    }

    var repos = flagutil.computeReposFromFlag(argv.r, {includeModules: true});

    yield repoutil.forEachRepo(repos, function*(repo) {
        // TODO: we should use gitutil.summaryOfChanges here.
        var cmd = executil.ARGS('git log --topo-order --no-merges');
        cmd.push(['--pretty=format:* %s']);
        var fromTag, toTag, hasOneTag;
        hasOneTag = false;
        if (argv['last-two-tags']) {
            var last_two = (yield gitutil.findMostRecentTag(repo.versionPrefix));
            if (last_two) {
                toTag = last_two[0];
                if (last_two.length > 1) {
                    fromTag = last_two[1];
                } else {
                    hasOneTag = true;
                    fromTag = toTag;
                }
            }
        } else {
            if (argv['from-tag']){
                fromTag = argv['from-tag'];
            } else {
                fromTag = (yield gitutil.findMostRecentTag(repo.versionPrefix))[0];
            }
            if (argv['to-tag']){
                toTag = argv['to-tag'];
            } else {
                toTag = 'master';
            }
        }

        if (!hasOneTag) {
            cmd.push(fromTag + '..' + toTag);
        }
        var repoDesc = repo.repoName;
        if (repo.path) {
            repoDesc += '/' + repo.path;
        }
        console.log('Finding commits in ' + repoDesc + ' from tag ' + fromTag + ' to tag ' + toTag);
        var output = yield executil.execHelper(cmd.concat(repoutil.getRepoIncludePath(repo)), true);
        if (output) {
            var newVersion;
            if (toTag === 'master') {
                delete require.cache[path.join(process.cwd(), 'package.json')];
                newVersion = require(path.join(process.cwd(), 'package.json')).version;
            } else {
                newVersion = toTag;
            }
            var final_notes = yield createNotes(repo, newVersion, output, argv['override-date']);
            fs.writeFileSync(relNotesFile, final_notes, {encoding: 'utf8'});
            return linkify.file(relNotesFile);
        }
    });
};

function backtick(text, token) {
    return text.replace(new RegExp(" " + token, "gi"), " `" + token + "`");
}

function bold(text, token) {
    return text.replace(new RegExp(" " + token, "gi"), " **" + token + "**");
}

var GITHUB_CLOSE_COMMIT_MSG = /^\*\s+Closes?\s+\#\d+$/gi;
var VIA_COHO_COMMIT_MSG = /\(via coho\)/gi

function *createNotes(repo, newVersion, changes, overrideDate) {
    // pump changes through JIRA linkifier first through a stream pipe
	var transformer = linkify.stream("CB");
	var read = new stream.Readable();
	read._read = function(){};// noop
	read.push(changes);
	read.push(null);
	var write = new stream.Writable();
	var data = '';
	write._write = function(chunk, encoding, done) {
		data += chunk.toString();
		done();
	}
	read.pipe(transformer).pipe(write);
    yield co_stream.wait(write); // wait for the writable stream to finish/end
    // remove any commit logs in the form "Close #xxx", used for closing github pull requests.
    var lines = data.split('\n');
    data = lines.filter(function(line) {
        return !(
           line.match(GITHUB_CLOSE_COMMIT_MSG) ||
           line.match(VIA_COHO_COMMIT_MSG)
        );
    }).join('\n');

    // some more release note linting: enclose in backticks certain tokens
    ['plugin.xml', 'package.json', 'config.xml', 'README', 'InAppBrowser'].forEach(function(token) {
        data = backtick(data, token);
    });
    flagutil.computeReposFromFlag('platforms').map(function(r) { return r.repoName; }).forEach(function(platform_name) {
        data = backtick(data, platform_name);
    });
    // bold platform labels (with optional version numbers, too)
    var version_labels = [];
    repoutil.repoGroups.platforms.filter(function(p) {
        // first only pull out the platform repos that we have explicitly labeled with nice version strings
        return p.versions && p.versions.length;
    }).forEach(function(p) {
        // next, generate the labels for later tokenization
        p.versions.forEach(function(v) {
            version_labels.push(p.title + ' ' + v);
        });
    });
    version_labels.forEach(function(label) {
        data = bold(data, label);
    });
    repoutil.repoGroups.platforms.map(function(r) { return r.title; }).forEach(function(platform) {
        data = bold(data, platform);
    });
    // then interpolate linkified changes into existing release notes and compose the final release notes string
    var relNotesData = fs.readFileSync(path.join(process.cwd(), repo, relNotesFile), {encoding: 'utf8'});
    var headerPos = relNotesData.indexOf('### ');
    var date;
    if (overrideDate) {
        date = new Date(overrideDate).toDateString().split(' ');
    } else {
        date = new Date().toDateString().split(' ');
    }
    return relNotesData.substr(0, headerPos) + "### " + newVersion + ' (' + date[1] + ' ' + date[2] + ', ' + date[3] + ')\n' + data + '\n\n' + relNotesData.substr(headerPos);
}

module.exports.createNotes = createNotes;
module.exports.FILE = relNotesFile;
