/**
 * Apeman new command.
 * @function apeman.commands.new
 * @param {string} appName - App name to create.
 * @param {object} options
 * @param {function} callback - Callback when done.
 * @author Taka Okunishi
 *
 */
var fs = require('fs'),
    tek = require('tek'),
    path = require('path'),
    print = require('../_print'),
    exec = require('child_process').exec,
    async = require('async');

exports = module.exports = function (projectName, options, callback) {
    var projectDir = path.resolve(projectName);
    async.series([
        exports._cleanAppDir(projectDir, options.force),
        exports._createAppDir(projectDir),
        exports._createApemanfile(projectDir, projectName, exports._defaultProtoytpeName)
    ], function (err) {
        if (err) {
            print.ng(err);
        } else {
            print.ok('New apeman project created:', projectDir);
        }
        print('');
        callback && callback(err);
    });
};

exports._defaultProtoytpeName = 'apc-abstract';

/**
 * Clean app directory.
 * @param dirname
 * @param force
 * @returns {Function}
 * @protected
 * @ignore
 */
exports._cleanAppDir = function (dirname, force) {
    return function (callback) {

        fs.exists(dirname, function (exists) {
            if (exists) {
                if (force) {
                    tek.file.rmdirRecursive(dirname, callback);
                } else {
                    var duplicateError = new exports._duplicateError(dirname);
                    callback(duplicateError);
                }
            } else {
                callback(null);
            }
        });
    };
};

/**
 * Create app dir.
 * @param {string} dirname
 * @returns {Function}
 * @protected
 * @ignore
 */
exports._createAppDir = function (dirname) {
    return function (callback) {
        fs.mkdir(dirname, callback);
    }
};

/**
 * Create apeman file.
 * @param {string} dirname - Directory name to create.
 * @param {string} projectName - Project name to create.
 * @param {string} prototypeName - Apeman file prototype name.
 * @returns {Function}
 * @protected
 * @ignore
 */
exports._createApemanfile = function (dirname, projectName, prototypeName) {
    var filename = path.resolve(dirname, 'Apemanfile.js');
    return function (callback) {
        exports._loadApemanFileTmpl(function (err, tmpl) {
            if (err) {
                callback(err);
                return;
            }
            exports._whoami(function (whoami) {
                var content = tmpl({
                    whoami: whoami,
                    projectName: projectName,
                    prototypeName: prototypeName
                });
                fs.writeFile(filename, content, callback);
            });
        });
    }
};

exports._findupApemanfile = require('../findup_apemanfile');


/**
 * Create a duplicate error
 * @param {string} appName
 * @returns {Error}
 * @protected
 * @ignore
 */
exports._duplicateError = function (appName) {
    var msg = [
        'Oops! Directory already exists at:\n\n    ', appName + ' \n\n' +
            'If you want to overwrite it, add -f option.'].join(' ');
    return new Error(msg);
};

/**
 * Load apemanfile template.
 * @param {function} callback - Callback when done.
 * @protected
 * @ignore
 */
exports._loadApemanFileTmpl = function (callback) {
    var tmplFile = path.resolve(__dirname, '../../tmpl/Apemanfile.js.hbs');
    fs.readFile(tmplFile, function (err, buffer) {
        if (err) {
            callback(err);
            return;
        }
        var Handlebars = require('handlebars');
        var tmpl = Handlebars.compile(buffer.toString());
        callback(null, tmpl);
    });
};

/**
 * Ask who am I.
 * @param callback
 * @protected
 * @ignore
 */
exports._whoami = function (callback) {
    exec('whoami', function (err, stdout, stdErr) {
        //Don't care even if command failed.
        callback((stdout || '').replace(/[\n\r]/g, ''));
    });
};