/* global module, require, console */
module.exports = function () {
    var exec = require('child_process').exec,
        inquirer = require('inquirer'),
        YAML = require('yamljs'),
        fs = require('fs-extra'),
        findUp = require('find-up'),
        path = require('path'),
        resolve = path.resolve,
        ora = require('ora'),
        process = require('process'),
        replace = require('replace-in-file'),
        applicationYMLFile = 'application.yaml',
        args = require('yargs').argv,
        projectKey,
        projectName = '',
        VENDOR = 'Cti',
        WEBROOT = '',
        spinner,
        replaceOptions = {
            files: 'scaffold/*.*',
            from: [/__PROJECTKEY__/g, /__PROJECTNAME__/g],
            to: ['demo', 'demo-theme']
        },
        setConfigCommand = 'npm config set magento2',
        setConfigSetLogLevelCommand = 'npm config set loglevel',
        PROJECT_PATH = (typeof process.argv[2] !== 'undefined') ? process.argv[2] :  '../../../../';


    /**
     * Helper to set the npm config variable (environment)
     * using shell command.
     *
     * @param key
     * @param value
     * @param callback
     */
    function setNPMConfigPath(key, value, callback) {
        var setPathCommand = setConfigCommand + ':' + key + ' ' + value;

        spinner.succeed('Set Project PATHS `' + setPathCommand + '`');
        exec(setPathCommand, function (error) {
            if (error !== null) {
                console.error('Cannot set paths error: ' + error);
            }

            if (typeof callback !== 'undefined') {
                callback(error);
            }
        });
    }

    /**
     * Helper to ser NPM Log level for the project
     * @param value
     * @param callback
     */
    function setNPMLogLevel(value, callback) {
        var setPathCommand = setConfigSetLogLevelCommand + ' ' + value;

        spinner.succeed('Set Log Levels to slient `' + value + '`');
        exec(setPathCommand, function (error) {
            if (error !== null) {
                console.error('Cannot set paths error: ' + error);
            }

            if (typeof callback !== 'undefined') {
                callback(error);
            }
        });
    }

    function isBlank(str) {
        return (!str || /^\s*$/.test(str));
    }

    function addLoader(label) {
        spinner = ora({ spinner: 'bouncingBar', text: '\033[33mRunning ' + label + '\033[0m', color: 'yellow'}).start();
    }

    function createThemeScaffold(themeSuffix, themeDirectoryPath) {
        var themeDirectory;
        if (typeof themeSuffix === 'undefined') {
            themeSuffix = '-theme';
        }

        if (typeof themeDirectoryPath === 'undefined') {
            themeDirectoryPath = PROJECT_PATH + WEBROOT + '/app/design/frontend/' + VENDOR + '/' + replaceOptions.to[0] + themeSuffix;
        }

        themeDirectory = resolve(themeDirectoryPath);

        setConfigCommand = 'npm config set ' +  projectKey + themeSuffix;
        setNPMConfigPath('projectPath', PROJECT_PATH, function () {
            // Set NPM Log level
            setNPMLogLevel('silent');

            if (WEBROOT !== '/' && WEBROOT !== '') {
                setNPMConfigPath('webRoot', WEBROOT + '/');
            }
        });

        // Create theme dir using scaffold
        fs.ensureDir(themeDirectory).then(function () {
            // Copy the contents from scaffold
            try {
                fs.copySync('./scaffold', themeDirectory);
                replaceOptions.files = themeDirectory + '/*.*';
                replace.sync(replaceOptions);
                spinner.succeed('Initialised Theme `' + replaceOptions.to[0] + themeSuffix + ' (' + replaceOptions.to[1]  + ')' + '`');
            } catch (err) {
                spinner.fail('Theme initialise failed `' + err + '`');
            }
        }).catch(function (err) {
            spinner.fail('Theme initialise failed `' + err + '`');
        });

        // Create admin theme dir using scaffold
        var adminHtmlDirectory = PROJECT_PATH + WEBROOT + '/app/design/adminhtml/';
        fs.ensureDir(adminHtmlDirectory).then(function () {
            // Copy the contents from scaffold
            try {
                fs.copySync('./scaffold-adminhtml', adminHtmlDirectory);
                spinner.succeed('Initialised Admin Theme');
            } catch (err) {
                spinner.fail('Admin Theme initialise failed `' + err + '`');
            }
        }).catch(function (err) {
            spinner.fail('Admin Theme initialise failed `' + err + '`');
        });
    }

    function init() {
        if (projectKey === false) {
            projectKey = 'demo';
        }

        if (typeof args.name === 'undefined') {
            inquirer.prompt({
                type: 'input',
                name: 'theme',
                message: 'Theme name (Required):',
                default: projectKey,
                validate: function (input) {
                    // Declare function as asynchronous, and save the done callback
                    var done = this.async();

                    // Do async stuff
                    setTimeout(function () {
                        if (isBlank(input)) {
                            // Pass the return value in the done callback
                            done('You need to provide a valid theme name');
                            return;
                        }
                        // Pass the return value in the done callback
                        done(null, true);
                    }, 200);
                }
            }).then(function (answer) {
                addLoader('Initialising theme `' + answer.theme + ' (' + projectName + ')`');
                replaceOptions.to = [answer.theme, projectName];
                createThemeScaffold();
            });
        } else {
            var projectThemeDirectoryPath,
                initString;

            projectKey = args.name;
            initString = 'Initialising theme `' + projectKey + ' (' + projectName + ')`';
            if (typeof args.path !== 'undefined') {
                projectThemeDirectoryPath = args.path;
                initString += ' on `' + projectThemeDirectoryPath + '`';
            }

            addLoader(initString);
            replaceOptions.to = [projectKey, projectName];
            createThemeScaffold('', projectThemeDirectoryPath);
        }
    }

    function getProjectKeyFromAppYML(ymlPath, callback) {
        YAML.load(ymlPath, function (results) {
            var result;

            for (result in results) {
                if (results.hasOwnProperty(result)) {
                    if (result === 'webroot') {
                        if (results[result] !== '/') {
                            WEBROOT = results[result];
                        }
                    }
                    if (result === 'key') {
                        projectKey = results[result];
                    }
                    if (result === 'name') {
                        projectName = results[result];
                    }
                }
            }

            callback();
        });
    }

    function findProjectPath() {
        var filepath = findUp.sync(applicationYMLFile);

        if (filepath !== null) {
            PROJECT_PATH = path.dirname(filepath) + '/';
            getProjectKeyFromAppYML(filepath, init);
        } else {
            init();
        }
    }

    findProjectPath();
}();
