/**
 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.
 */

const pify = require('pify');
const which = pify(require('which'));
const path = require('path');
const fs = require('fs-extra');
const { CordovaError, events, superspawn } = require('cordova-common');
const npa = require('npm-package-arg');
const pacote = require('pacote');
const semver = require('semver');

// pify's multiArgs unfortunately causes resolve to wrap errors in an Array.
// Thus we wrap the function again to unpack these wrapped errors.
const rslv = pify(require('resolve'), { multiArgs: true });
const resolve = (...args) => rslv(...args).catch(([err]) => { throw err; });

/**
 * Installs a module from npm, a git url or the local file system.
 *
 * @param {String} target       A spec for the package to be installed
 *                              (anything supported by `npm install`)
 * @param {String} dest         Location where to install the package
 * @param {Object} [opts={}]    Additional options
 *
 * @return {Promise<string>}    Absolute path to the installed package
 */
module.exports = async function (target, dest, opts = {}) {
    try {
        if (!dest || !target) {
            throw new CordovaError('Need to supply a target and destination');
        }

        // Create dest if it doesn't exist yet
        fs.ensureDirSync(dest);

        // First try to determine the name from the spec using npa. This is very cheap.
        let { name, rawSpec } = npa(target, dest);

        if (!name) {
            // If that fails, get out the big guns and fetch a full manifest using pacote.
            ({ name } = await pacote.manifest(target, { where: dest }));
        } else if (semver.validRange(rawSpec)) {
            // If the provided spec is a name and a version range, we look for
            // an installed package that satisfies the requested version range
            try {
                const [pkgPath, { version }] = await resolvePathToPackage(name, dest);
                if (semver.satisfies(version, rawSpec)) return pkgPath;
            } catch (err) {
                // Ignore MODULE_NOT_FOUND errors from resolvePathToPackage
                if (err.code !== 'MODULE_NOT_FOUND') throw err;
            }
        }

        await installPackage(target, dest, opts);

        return (await resolvePathToPackage(name, dest))[0];
    } catch (err) {
        throw new CordovaError(err);
    }
};

// Installs the package specified by target and returns the installation path
async function installPackage (target, dest, opts) {
    await isNpmInstalled();

    // Ensure that `npm` installs to `dest` and not any of its ancestors
    await fs.ensureDir(path.join(dest, 'node_modules'));

    // Run `npm` to install requested package
    const args = npmArgs(target, opts);
    events.emit('verbose', `fetch: Installing ${target} to ${dest}`);
    await superspawn.spawn('npm', args, { cwd: dest });
}

function npmArgs (target, opts) {
    const args = ['install', target];
    opts = opts || {};

    if (opts.save_exact) {
        args.push('--save-exact');
    } else if (opts.save) {
        args.push('--save-dev');
    } else {
        args.push('--no-save');
    }
    return args;
}

// Resolves to installation path and package.json of package `name` starting
// from `basedir`
async function resolvePathToPackage (name, basedir) {
    const paths = (process.env.NODE_PATH || '')
        .split(path.delimiter)
        .filter(p => p);

    // We resolve the path to the module's package.json to avoid getting the
    // path to `main` which could be located anywhere in the package
    const [pkgJsonPath, pkgJson] = await resolve(`${name}/package.json`, { paths, basedir });

    return [path.dirname(pkgJsonPath), pkgJson];
}

/**
 * Checks to see if npm is installed on the users system
 *
 * @return {Promise<string>} Absolute path to npm.
 */
async function isNpmInstalled () {
    return which('npm').catch(_ => {
        throw new CordovaError('"npm" command line tool is not installed: make sure it is accessible on your PATH.');
    });
}

module.exports.isNpmInstalled = isNpmInstalled;

/**
 * Uninstalls the package `target` from `dest` using given options.
 *
 * @param {String} target       Name of the package to be uninstalled
 * @param {String} dest         Location from where to uninstall the package
 * @param {Object} [opts={}]    Additional options
 *
 * @return {Promise<string>}    Resolves when removal has finished
 */
module.exports.uninstall = async (target, dest, opts) => {
    const fetchArgs = ['uninstall'];
    opts = opts || {};

    try {
        // check if npm is installed on the system
        await isNpmInstalled();

        if (dest && target) {
            // add target to fetchArgs Array
            fetchArgs.push(target);
        } else throw 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 --save-dev flag to npm uninstall command
        if (opts.save) {
            fetchArgs.push('--save-dev');
        } 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);
    } catch (err) {
        throw new CordovaError(err);
    }
};
