#!/usr/bin/env node
/*
  Copyright (C) 2012 Yusuke Suzuki <utatane.tea@gmail.com>

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/*jslint sloppy:true node:true */

var fs = require('fs'),
    path = require('path'),
    root = path.join(path.dirname(fs.realpathSync(__filename)), '..'),
    escodegen = require(root),
    esprima = require('esprima'),
    RegistryClient = require('bower-registry-client'),
    semver = require('semver'),
    child_process = require('child_process'),
    Promise = require('bluebird');

function exec(cmd) {
    return new Promise(function (resolve, reject) {
        console.log(cmd);
        child_process.exec(cmd, function (error, stdout, stderr) {
            resolve(error, stdout, stderr);
        });
    });
}

(function () {
    var config, matched, version, devVersion, registry;

    config = JSON.parse(fs.readFileSync(path.join(root, 'package.json'), 'utf-8'));
    devVersion = config.version;
    matched = devVersion.match(/^(\d+\.\d+\.\d+(-\d+)?)$/);
    if (!matched) {
        console.error('version style "' + devVersion + '" is not matched to X.X.X[-X].');
        process.exit(1);
    }

    version = matched[1];
    config.version = version;

    registry = new RegistryClient();

    function ping(memo, name) {
        return new Promise(function (resolve, reject) {
            var pattern;
            console.log('[' + name + '] ' + 'send ping');

            pattern = config.dependencies[name];

            registry.lookup(name, function (err, entry) {
                var i, iz, version;

                if (err) {
                    console.error('[' + name + '] ' + err.message + '. skip this dependency');
                    return;
                }

                console.log('[' + name + '] ' + 'received result');
                memo[name] = pattern;
                resolve();
            });
        });
    }

    exec('git branch -D ' + version)
    .then(function () {
        return exec('git checkout -b ' + version);
    })
    .then(function generateConfigs() {
        var dependencies = {},
            optionalDependencies = {},
            promises;
        fs.writeFileSync(path.join(root, 'package.json'), JSON.stringify(config, null, 4), 'utf-8');

        // generate component.json
        promises =
            Object.keys(config.dependencies).map(ping.bind(null, dependencies)).concat(
                Object.keys(config.optionalDependencies).map(ping.bind(null, optionalDependencies)));
        return Promise.all(promises).then(function () {
            config.dependencies = dependencies;
            config.optionalDependencies = optionalDependencies;
            fs.writeFileSync(path.join(root, 'component.json'), JSON.stringify(config, null, 4), 'utf-8');
        });
    })
    .then(function browserify() {
        return exec('npm run-script build');
    })
    .then(function browserify() {
        return exec('npm run-script build-min');
    })
    .then(function gitAdd() {
        return exec('git add "' + root + '"');
    })
    .then(function gitCommit() {
        return exec('git commit -m "Bump version ' + version + '"');
    })
    .then(function gitDeleteTag() {
        return exec('git tag -d ' + version);
    })
    .then(function gitAddTag() {
        return exec('git tag -a ' + version + ' -m "version ' + version + '"');
    })
    .then(function () {
        console.log('Finally you should execute npm publish and git push --tags');
    });
}());

/* vim: set sw=4 ts=4 et tw=80 : */
