/**
 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 execa = require('execa');
const which = require('which');
const path = require('node:path');
const fs = require('node:fs/promises');
const { CordovaError, events } = require('cordova-common');
const npa = require('npm-package-arg');
const pacote = require('pacote');
const semver = require('semver');

function resolvePackage (...args) {
    return new Promise((resolve, reject) => {
        require('resolve')(...args, (err, ...result) => {
            if (err) {
                reject(err);
            } else {
                resolve(result);
            }
        });
    });
}

/**
 * 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
        await fs.mkdir(dest, { recursive: true });

        // 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,
                Arborist: require('@npmcli/arborist')
            }));
        } 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.mkdir(path.join(dest, 'node_modules'), { recursive: true });

    // Run `npm` to install requested package
    const args = npmArgs(target, opts);
    events.emit('verbose', `fetch: Installing ${target} to ${dest}`);
    return execa('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 resolvePackage(`${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 () {
    try {
        return await which('npm');
    } catch (e) {
        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 execa('npm', fetchArgs, opts);
    } catch (err) {
        throw new CordovaError(err);
    }
};
