/**
    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 fs = require('fs-extra');

var path = require('path');

var Q = require('q');
var tmp = require('tmp');
var isUrl = require('is-url');
var isObject = require('isobject');
var pathIsInside = require('path-is-inside');
var requireFresh = require('import-fresh');
var validateIdentifier = require('valid-identifier');

var fetch = require('cordova-fetch');
var events = require('cordova-common').events;
var CordovaError = require('cordova-common').CordovaError;
var ConfigParser = require('cordova-common').ConfigParser;
var CordovaLogger = require('cordova-common').CordovaLogger.get();

const DEFAULT_VERSION = '1.0.0';

/**
 * Sets up to forward events to another instance, or log console.
 * This will make the create internal events visible outside
 * @param  {EventEmitter} externalEventEmitter An EventEmitter instance that will be used for
 *   logging purposes. If no EventEmitter provided, all events will be logged to console
 * @return {EventEmitter}
 */
function setupEvents (externalEventEmitter) {
    if (externalEventEmitter) {
        // This will make the platform internal events visible outside
        events.forwardEventsTo(externalEventEmitter);
    // There is no logger if external emitter is not present,
    // so attach a console logger
    } else {
        CordovaLogger.subscribe(events);
    }
    return events;
}

module.exports = cordovaCreateLegacyAdapter;

/**
* Legacy interface. See README for documentation
*/
function cordovaCreateLegacyAdapter (dir, id, name, cfg, extEvents) {
    // Unwrap and shallow-clone that nasty nested config object
    const opts = Object.assign({}, ((cfg || {}).lib || {}).www);

    if (id) opts.id = id;
    if (name) opts.name = name;
    if (extEvents) opts.extEvents = extEvents;

    return Q(cordovaCreate(dir, opts));
}

/**
 * Creates a new cordova project in the given directory.
 *
 * @param {string} dest         directory where the project will be created.
 * @param {Object} [opts={}]    options to be used for creating the project.
 * @returns {Promise}           Resolves when project creation has finished.
 */
function cordovaCreate (dest, opts = {}) {
    // TODO this is to avoid having a huge diff. Remove later.
    let dir = dest;

    return Promise.resolve().then(function () {
        if (!dir) {
            throw new CordovaError('Directory not specified. See `cordova help`.');
        }

        if (!isObject(opts)) {
            throw new CordovaError('Given options must be an object');
        }

        // Shallow copy opts
        opts = Object.assign({}, opts);

        events = setupEvents(opts.extEvents);
        events.emit('verbose', 'Using detached cordova-create');

        // Make absolute.
        dir = path.resolve(dir);

        if (fs.existsSync(dir) && fs.readdirSync(dir).length > 0) {
            throw new CordovaError('Path already exists and is not empty: ' + dir);
        }

        if (opts.id && !validateIdentifier(opts.id)) {
            throw new CordovaError('App id contains a reserved word, or is not a valid identifier.');
        }

        // This was changed from "uri" to "url", but checking uri for backwards compatibility.
        opts.url = opts.url || opts.uri;

        if (!opts.url) {
            opts.url = require.resolve('cordova-app-hello-world');
            opts.template = true;
        }

        // Ensure that the destination is outside the template location
        if (pathIsInside(dir, opts.url)) {
            throw new CordovaError(
                `Cannot create project "${dir}" inside the template used to create it "${opts.url}".`
            );
        }
    })
        .then(function () {
            // Finally, Ready to start!
            events.emit('log', 'Creating a new cordova project.');

            // If symlink, don't fetch
            if (opts.link) {
                return opts.url;
            }

            var isGit = opts.template && isUrl(opts.url);
            var isNPM = opts.template && (opts.url.indexOf('@') > -1 || !fs.existsSync(path.resolve(opts.url))) && !isGit;
            // Always use cordova fetch to obtain the npm or git template
            if (isGit || isNPM) {
                var target = opts.url;
                events.emit('verbose', 'Using cordova-fetch for ' + target);
                return fetch(target, getSelfDestructingTempDir(), {})
                    .catch(function (err) {
                        events.emit('error', '\x1B[1m \x1B[31m Error from Cordova Fetch: ' + err.message);
                        events.emit('error', 'The template you are trying to use is invalid.' +
                        ' Make sure you follow the template guide found here https://cordova.apache.org/docs/en/latest/guide/cli/template.html.' +
                        ' Templates now require a package.json.');
                        throw err;
                    });
            // If assets are not online, resolve as a relative path on local computer
            } else {
                return path.resolve(opts.url);
            }
        })
        .then(function (input_directory) {
            var import_from_path = input_directory;

            // handle when input wants to specify sub-directory (specified in index.js as "dirname" export);
            var isSubDir = false;
            try {
                var templatePkg = requireFresh(input_directory);
                if (templatePkg && templatePkg.dirname) {
                    import_from_path = templatePkg.dirname;
                    isSubDir = true;
                }
            } catch (e) {
                events.emit('verbose', 'index.js does not specify valid sub-directory: ' + input_directory);
                isSubDir = false;
            }

            if (!fs.existsSync(import_from_path)) {
                throw new CordovaError('Could not find directory: ' +
                    import_from_path);
            }

            var dirAlreadyExisted = fs.existsSync(dir);
            if (!dirAlreadyExisted) {
                fs.mkdirSync(dir);
            }

            try {
                // Copy files from template to project
                if (opts.template) {
                    events.emit('verbose', 'Copying assets.');
                    copyTemplateFiles(import_from_path, dir, isSubDir);
                }

                // If --link, link merges, hooks, www, and config.xml (and/or copy to root)
                if (opts.link) {
                    events.emit('verbose', 'Symlinking assets.');
                    linkFromTemplate(import_from_path, dir);
                }

                // If following were not copied/linked from template, copy from stock app hello world
                // TODO: get stock package.json if template does not contain package.json;
                copyIfNotExists(stockAssetPath('www'), path.join(dir, 'www'));
                copyIfNotExists(stockAssetPath('hooks'), path.join(dir, 'hooks'));
                var configXmlExists = projectConfig(dir); // moves config to root if in www
                if (!configXmlExists) {
                    fs.copySync(stockAssetPath('config.xml'), path.join(dir, 'config.xml'));
                }
            } catch (e) {
                if (!dirAlreadyExisted) {
                    fs.removeSync(dir);
                }
                if (process.platform.slice(0, 3) === 'win' && e.code === 'EPERM') {
                    throw new CordovaError('Symlinks on Windows require Administrator privileges');
                }
                throw e;
            }

            var pkgjsonPath = path.join(dir, 'package.json');
            // Update package.json name and version fields
            if (fs.existsSync(pkgjsonPath)) {
                var pkgjson = requireFresh(pkgjsonPath);

                // Pkjson.displayName should equal config's name.
                if (opts.name) {
                    pkgjson.displayName = opts.name;
                }
                // Pkjson.name should equal config's id.
                if (opts.id) {
                    pkgjson.name = opts.id.toLowerCase();
                } else {
                    // Use default name.
                    pkgjson.name = 'helloworld';
                }

                pkgjson.version = DEFAULT_VERSION;
                fs.writeFileSync(pkgjsonPath, JSON.stringify(pkgjson, null, 4), 'utf8');
            }

            // Create basic project structure.
            fs.ensureDirSync(path.join(dir, 'platforms'));
            fs.ensureDirSync(path.join(dir, 'plugins'));

            var configPath = path.join(dir, 'config.xml');
            // only update config.xml if not a symlink
            if (!fs.lstatSync(configPath).isSymbolicLink()) {
                // Write out id, name and default version to config.xml
                var conf = new ConfigParser(configPath);
                if (opts.id) conf.setPackageName(opts.id);
                if (opts.name) conf.setName(opts.name);
                conf.setVersion(DEFAULT_VERSION);
                conf.write();
            }
        });
}

/**
 * Recursively copies folder to destination if folder is not found in destination (including symlinks).
 * @param  {string} src for copying
 * @param  {string} dst for copying
 * @return No return value
 */
function copyIfNotExists (src, dst) {
    if (!fs.existsSync(dst) && src) {
        fs.copySync(src, dst);
    }
}

/**
 * Copies template files, and directories into a Cordova project directory.
 * If the template is a www folder, the www folder is simply copied
 * Otherwise if the template exists in a subdirectory everything is copied
 * Otherwise package.json, RELEASENOTES.md, .git, NOTICE, LICENSE, COPYRIGHT, and .npmignore are not copied over.
 * A template directory, and project directory must be passed.
 * templateDir - Template directory
 * projectDir - Project directory
 * isSubDir - boolean is true if template has subdirectory structure (see code around line 229)
 */
function copyTemplateFiles (templateDir, projectDir, isSubDir) {
    var copyPath;
    // if template is a www dir
    if (path.basename(templateDir) === 'www') {
        copyPath = path.resolve(templateDir);
        fs.copySync(copyPath, path.resolve(projectDir, 'www'));
    } else {
        var templateFiles = fs.readdirSync(templateDir);
        // Remove directories, and files that are unwanted
        if (!isSubDir) {
            var excludes = ['package.json', 'RELEASENOTES.md', '.git', 'NOTICE', 'LICENSE', 'COPYRIGHT', '.npmignore'];
            templateFiles = templateFiles.filter(function (value) {
                return excludes.indexOf(value) < 0;
            });
        }
        // Copy each template file after filter
        templateFiles.forEach(f => {
            copyPath = path.resolve(templateDir, f);
            fs.copySync(copyPath, path.resolve(projectDir, f));
        });
    }
}

/**
 * Find config file in project directory or www directory
 * If file is in www directory, move it outside
 * @param  {String} project directory to be searched
 * @return {String or False} location of config file; if none exists, returns false
 */
function projectConfig (projectDir) {
    var rootPath = path.join(projectDir, 'config.xml');
    var wwwPath = path.join(projectDir, 'www', 'config.xml');
    if (fs.existsSync(rootPath)) {
        return rootPath;
    } else if (fs.existsSync(wwwPath)) {
        fs.renameSync(wwwPath, rootPath);
        return wwwPath;
    }
    return false;
}

/**
 * Removes existing files and symlinks them if they exist.
 * Symlinks folders: www, merges, hooks
 * Symlinks file: config.xml (but only if it exists outside of the www folder)
 * If config.xml exists inside of template/www, COPY (not link) it to project/
 * */
function linkFromTemplate (templateDir, projectDir) {
    var linkSrc, linkDst, linkFolders, copySrc, copyDst;
    function rmlinkSync (src, dst, type) {
        if (src && dst) {
            fs.removeSync(dst);
            if (fs.existsSync(src)) {
                fs.symlinkSync(src, dst, type);
            }
        }
    }
    // if template is a www dir
    if (path.basename(templateDir) === 'www') {
        linkSrc = path.resolve(templateDir);
        linkDst = path.join(projectDir, 'www');
        rmlinkSync(linkSrc, linkDst, 'dir');
        copySrc = path.join(templateDir, 'config.xml');
    } else {
        linkFolders = ['www', 'merges', 'hooks'];
        // Link each folder
        for (var i = 0; i < linkFolders.length; i++) {
            linkSrc = path.join(templateDir, linkFolders[i]);
            linkDst = path.join(projectDir, linkFolders[i]);
            rmlinkSync(linkSrc, linkDst, 'dir');
        }
        linkSrc = path.join(templateDir, 'config.xml');
        linkDst = path.join(projectDir, 'config.xml');
        rmlinkSync(linkSrc, linkDst, 'file');
        copySrc = path.join(templateDir, 'www', 'config.xml');
    }
    // if template/www/config.xml then copy to project/config.xml
    copyDst = path.join(projectDir, 'config.xml');
    if (!fs.existsSync(copyDst) && fs.existsSync(copySrc)) {
        fs.copySync(copySrc, copyDst);
    }
}

function stockAssetPath (p) {
    return path.join(require('cordova-app-hello-world').dirname, p);
}

// Creates temp dir that is deleted on process exit
function getSelfDestructingTempDir () {
    return tmp.dirSync({
        prefix: 'cordova-create-',
        unsafeCleanup: true
    }).name;
}
