/**
 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 Q = require('q');
var shell = require('shelljs');
var superspawn = require('cordova-common').superspawn;
var events = require('cordova-common').events;
var depls = require('dependency-ls');
var url = require('url');
var path = require('path');
var fs = require('fs');
var CordovaError = require('cordova-common').CordovaError;
var isUrl = require('is-url');
var isGitUrl = require('is-git-url');
var hostedGitInfo = require('hosted-git-info');

/*
 * A function that npm installs a module from npm or a git url
 *
 * @param {String} target   the packageID or git url
 * @param {String} dest     destination of where to install the module
 * @param {Object} opts     [opts={save:true}] options to pass to fetch module
 *
 * @return {String|Promise}    Returns string of the absolute path to the installed module.
 *
 */
module.exports = function (target, dest, opts) {
    var fetchArgs = opts.link ? ['link'] : ['install'];
    opts = opts || {};
    var tree1;
    var nodeModulesDir = dest;

    // check if npm is installed
    return module.exports.isNpmInstalled()
        .then(function () {
            if (dest && target) {
                // add target to fetchArgs Array
                fetchArgs.push(target);

                // append node_modules to nodeModulesDir if it doesn't come included
                if (path.basename(dest) !== 'node_modules') {
                    nodeModulesDir = path.resolve(path.join(dest, 'node_modules'));
                }
                // create node_modules if it doesn't exist
                if (!fs.existsSync(nodeModulesDir)) {
                    shell.mkdir('-p', nodeModulesDir);
                }
            } else return Q.reject(new CordovaError('Need to supply a target and destination'));

            // set the directory where npm install will be run
            opts.cwd = dest;
            // npm should use production by default when install is npm run

            if ((opts.production) || (opts.production === undefined)) {
                fetchArgs.push('--production');
                opts.production = true;
            }

            // if user added --save flag, pass it to npm install command
            if (opts.save_exact) {
                events.emit('verbose', 'saving exact');
                fetchArgs.push('--save-exact');
            } else if (opts.save) {
                events.emit('verbose', 'saving');
                fetchArgs.push('--save');
            } else {
                fetchArgs.push('--no-save');
            }
            // Grab json object of installed modules before npm install
            return depls(nodeModulesDir);
        })
        .then(function (depTree) {
            tree1 = depTree;
            // install new module
            return superspawn.spawn('npm', fetchArgs, opts);
        })
        .then(function (output) {
            // Grab object of installed modules after npm install
            return depls(nodeModulesDir);
        })
        .then(function (depTree2) {
            var tree2 = depTree2;

            // getJsonDiff will fail if the module already exists in node_modules.
            // Need to use trimID in that case.
            // This could happen on a platform update.
            var id = getJsonDiff(tree1, tree2) || trimID(target);
            return module.exports.getPath(id, nodeModulesDir, target);
        })
        .fail(function (err) {
            return Q.reject(new CordovaError(err));
        });
};

/*
 * Takes two JSON objects and returns the key of the new property as a string.
 * If a module already exists in node_modules, the diff will be blank.
 * cordova-fetch will use trimID in that case.
 *
 * @param {Object} obj1     json object representing installed modules before latest npm install
 * @param {Object} obj2     json object representing installed modules after latest npm install
 *
 * @return {String}         String containing the key value of the difference between the two objects
 *
 */
function getJsonDiff (obj1, obj2) {
    var result = [];
    // regex to filter out peer dependency warnings from result
    var re = /UNMET PEER DEPENDENCY/;

    for (var key in obj2) {
        // if it isn't a unmet peer dependency, continue
        if (key.search(re) === -1) {
            if (obj2[key] !== obj1[key]) {
                result.push(key);
            }
        }
    }
    if (result.length > 1) {
        // something went wrong if we have more than one module installed at a time
        return false;
    }
    // only return the first element
    return result[0];
}
/*
 * Takes the specified target and returns the moduleID
 * If the git repoName is different than moduleID, then the
 * output from this function will be incorrect. This is the
 * backup way to get ID. getJsonDiff is the preferred way to
 * get the moduleID of the installed module.
 *
 * @param {String} target    target that was passed into cordova-fetch.
 *                           can be moduleID, moduleID@version or gitURL
 *
 * @return {String} ID       moduleID without version.
 */
function trimID (target) {
    var parts;
    // If GITURL, set target to repo name
    var gitInfo = hostedGitInfo.fromUrl(target);
    if (gitInfo) {
        target = gitInfo.project;
    } else if (isUrl(target) || isGitUrl(target)) {
        // strip away .git and everything that follows
        var strippedTarget = target.split('.git');
        var re = /.*\/(.*)/;
        // Grabs everything in url after last `/`
        parts = strippedTarget[0].match(re);

        target = parts[1];
    }

    // If local path exists, try to get plugin id from package.json or set target to final directory
    if (fs.existsSync(target)) {
        var pluginId;
        var pkgJsonPath = path.join(target, 'package.json');

        if (fs.existsSync(pkgJsonPath)) {
            pluginId = JSON.parse(fs.readFileSync(pkgJsonPath)).name;
        }

        target = pluginId || path.basename(target);
    }

    // strip away everything after '@'
    // also support scoped packages
    if (target.indexOf('@') !== -1) {
        parts = target.split('@');
        if (parts.length > 1 && parts[0] === '') {
            // scoped package
            target = '@' + parts[1];
        } else {
            target = parts[0];
        }
    }

    return target;
}

/*
 * Takes the moduleID and destination and returns an absolute path to the module
 *
 * @param {String} id       the packageID
 * @param {String} dest     destination of where to fetch the modules
 *
 * @return {String|Error}  Returns the absolute url for the module or throws a error
 *
 */

function getPath (id, dest, target) {
    var destination = path.resolve(path.join(dest, id));
    var finalDest = fs.existsSync(destination) ? destination : searchDirForTarget(dest, target);

    if (!finalDest) {
        throw new CordovaError('Failed to get absolute path to installed module');
    }

    return finalDest;
}

module.exports.getPath = getPath;
/*
 * Make an additional search in destination folder using repository.url property from package.json
 *
 * @param {String} dest     destination of where to fetch the modules
 * @param {String} target   target that was passed into cordova-fetch. can be moduleID, moduleID@version or gitURL
 *
 * @return {String}         Returns the absolute url for the module or null
 *
 */

function searchDirForTarget (dest, target) {
    if (!isUrl(target)) {
        return;
    }

    var targetPathname = url.parse(target).pathname;

    var pkgJsonPath = fs.readdirSync(dest).map(function (dir) {
        return path.join(dest, dir, 'package.json');
    })
        .filter(fs.existsSync)
        .find(function (pkgJsonPath) {
            var repo = JSON.parse(fs.readFileSync(pkgJsonPath)).repository;
            return repo && url.parse(repo.url).pathname === targetPathname;
        });

    return pkgJsonPath && path.dirname(pkgJsonPath);
}

/*
 * Checks to see if npm is installed on the users system
 * @return {Promise|Error} Returns true or a cordova error.
 */

function isNpmInstalled () {
    if (!shell.which('npm')) {
        return Q.reject(new CordovaError('"npm" command line tool is not installed: make sure it is accessible on your PATH.'));
    }
    return Q();
}

module.exports.isNpmInstalled = isNpmInstalled;
/*
 * A function that deletes the target from node_modules and runs npm uninstall
 *
 * @param {String} target   the packageID
 * @param {String} dest     destination of where to uninstall the module from
 * @param {Object} opts     [opts={save:true}] options to pass to npm uninstall
 *
 * @return {Promise|Error}    Returns a promise with the npm uninstall output or an error.
 *
 */
module.exports.uninstall = function (target, dest, opts) {
    var fetchArgs = ['uninstall'];
    opts = opts || {};

    // check if npm is installed on the system
    return isNpmInstalled()
        .then(function () {
            if (dest && target) {
                // add target to fetchArgs Array
                fetchArgs.push(target);
            } else return Q.reject(new CordovaError('Need to supply a target and destination'));

            // set the directory where npm uninstall will be run
            opts.cwd = dest;

            // if user added --save flag, pass it to npm uninstall command
            if (opts.save) {
                fetchArgs.push('--save');
            } else {
                fetchArgs.push('--no-save');
            }

            // run npm uninstall, this will remove dependency
            // from package.json if --save was used.
            return superspawn.spawn('npm', fetchArgs, opts);
        })
        .then(function (res) {
            var pluginDest = path.join(dest, 'node_modules', target);
            if (fs.existsSync(pluginDest)) {
                shell.rm('-rf', pluginDest);
            }
            return res;
        })
        .fail(function (err) {
            return Q.reject(new CordovaError(err));
        });
};
