/*
 * Licensed 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 fs = require('fs-extra');
var path = require('path');
var endent = require('endent');
var mungeutil = require('./ConfigChanges/munge-util');

function PlatformJson (filePath, platform, root) {
    this.filePath = filePath;
    this.platform = platform;
    this.root = fix_munge(root || {});
}

PlatformJson.load = function (plugins_dir, platform) {
    var filePath = path.join(plugins_dir, platform + '.json');
    var root = null;
    if (fs.existsSync(filePath)) {
        root = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
    }
    return new PlatformJson(filePath, platform, root);
};

PlatformJson.prototype.save = function () {
    fs.outputJsonSync(this.filePath, this.root, { spaces: 2 });
};

/**
 * Indicates whether the specified plugin is installed as a top-level (not as
 *  dependency to others)
 * @method function
 * @param  {String} pluginId A plugin id to check for.
 * @return {Boolean} true if plugin installed as top-level, otherwise false.
 */
PlatformJson.prototype.isPluginTopLevel = function (pluginId) {
    return this.root.installed_plugins[pluginId];
};

/**
 * Indicates whether the specified plugin is installed as a dependency to other
 *  plugin.
 * @method function
 * @param  {String} pluginId A plugin id to check for.
 * @return {Boolean} true if plugin installed as a dependency, otherwise false.
 */
PlatformJson.prototype.isPluginDependent = function (pluginId) {
    return this.root.dependent_plugins[pluginId];
};

/**
 * Indicates whether plugin is installed either as top-level or as dependency.
 * @method function
 * @param  {String} pluginId A plugin id to check for.
 * @return {Boolean} true if plugin installed, otherwise false.
 */
PlatformJson.prototype.isPluginInstalled = function (pluginId) {
    return this.isPluginTopLevel(pluginId) ||
        this.isPluginDependent(pluginId);
};

PlatformJson.prototype.addPlugin = function (pluginId, variables, isTopLevel) {
    var pluginsList = isTopLevel ?
        this.root.installed_plugins :
        this.root.dependent_plugins;

    pluginsList[pluginId] = variables;

    return this;
};

/**
 * @chaining
 * Generates and adds metadata for provided plugin into associated <platform>.json file
 *
 * @param   {PluginInfo}  pluginInfo  A pluginInfo instance to add metadata from
 * @returns {this} Current PlatformJson instance to allow calls chaining
 */
PlatformJson.prototype.addPluginMetadata = function (pluginInfo) {

    var installedModules = this.root.modules || [];

    var installedPaths = installedModules.map(function (installedModule) {
        return installedModule.file;
    });

    var modulesToInstall = pluginInfo.getJsModules(this.platform)
        .map(function (module) {
            return new ModuleMetadata(pluginInfo.id, module);
        })
        .filter(function (metadata) {
            // Filter out modules which are already added to metadata
            return !installedPaths.includes(metadata.file);
        });

    this.root.modules = installedModules.concat(modulesToInstall);

    this.root.plugin_metadata = this.root.plugin_metadata || {};
    this.root.plugin_metadata[pluginInfo.id] = pluginInfo.version;

    return this;
};

PlatformJson.prototype.removePlugin = function (pluginId, isTopLevel) {
    var pluginsList = isTopLevel ?
        this.root.installed_plugins :
        this.root.dependent_plugins;

    delete pluginsList[pluginId];

    return this;
};

/**
 * @chaining
 * Removes metadata for provided plugin from associated file
 *
 * @param   {PluginInfo}  pluginInfo A PluginInfo instance to which modules' metadata
 *   we need to remove
 *
 * @returns {this} Current PlatformJson instance to allow calls chaining
 */
PlatformJson.prototype.removePluginMetadata = function (pluginInfo) {
    var modulesToRemove = pluginInfo.getJsModules(this.platform)
        .map(function (jsModule) {
            return ['plugins', pluginInfo.id, jsModule.src].join('/');
        });

    var installedModules = this.root.modules || [];
    this.root.modules = installedModules
        .filter(function (installedModule) {
            // Leave only those metadatas which 'file' is not in removed modules
            return !modulesToRemove.includes(installedModule.file);
        });

    if (this.root.plugin_metadata) {
        delete this.root.plugin_metadata[pluginInfo.id];
    }

    return this;
};

PlatformJson.prototype.addInstalledPluginToPrepareQueue = function (pluginDirName, vars, is_top_level, force) {
    this.root.prepare_queue.installed.push({ 'plugin': pluginDirName, 'vars': vars, 'topLevel': is_top_level, 'force': force });
};

PlatformJson.prototype.addUninstalledPluginToPrepareQueue = function (pluginId, is_top_level) {
    this.root.prepare_queue.uninstalled.push({ 'plugin': pluginId, 'id': pluginId, 'topLevel': is_top_level });
};

/**
 * Moves plugin, specified by id to top-level plugins. If plugin is top-level
 *  already, then does nothing.
 * @method function
 * @param  {String} pluginId A plugin id to make top-level.
 * @return {PlatformJson} PlatformJson instance.
 */
PlatformJson.prototype.makeTopLevel = function (pluginId) {
    var plugin = this.root.dependent_plugins[pluginId];
    if (plugin) {
        delete this.root.dependent_plugins[pluginId];
        this.root.installed_plugins[pluginId] = plugin;
    }
    return this;
};

/**
 * Generates a metadata for all installed plugins and js modules. The resultant
 *   string is ready to be written to 'cordova_plugins.js'
 *
 * @returns {String} cordova_plugins.js contents
 */
PlatformJson.prototype.generateMetadata = function () {
    const stringify = o => JSON.stringify(o, null, 2);
    return endent`
        cordova.define('cordova/plugin_list', function(require, exports, module) {
          module.exports = ${stringify(this.root.modules)};
          module.exports.metadata = ${stringify(this.root.plugin_metadata)};
        });
    `;
};

/**
 * @chaining
 * Generates and then saves metadata to specified file. Doesn't check if file exists.
 *
 * @param {String} destination  File metadata will be written to
 * @return {PlatformJson} PlatformJson instance
 */
PlatformJson.prototype.generateAndSaveMetadata = function (destination) {
    fs.outputFileSync(destination, this.generateMetadata());

    return this;
};

// convert a munge from the old format ([file][parent][xml] = count) to the current one
function fix_munge (root) {
    root.prepare_queue = root.prepare_queue || { installed: [], uninstalled: [] };
    root.config_munge = root.config_munge || { files: {} };
    root.installed_plugins = root.installed_plugins || {};
    root.dependent_plugins = root.dependent_plugins || {};

    var munge = root.config_munge;
    if (!munge.files) {
        var new_munge = { files: {} };
        for (var file in munge) {
            for (var selector in munge[file]) {
                for (var xml_child in munge[file][selector]) {
                    var val = parseInt(munge[file][selector][xml_child]);
                    for (var i = 0; i < val; i++) {
                        mungeutil.deep_add(new_munge, [file, selector, { xml: xml_child, count: val }]);
                    }
                }
            }
        }
        root.config_munge = new_munge;
    }

    return root;
}

/**
 * @constructor
 * @class ModuleMetadata
 *
 * Creates a ModuleMetadata object that represents module entry in 'cordova_plugins.js'
 *   file at run time
 *
 * @param {String}  pluginId  Plugin id where this module installed from
 * @param (JsModule|Object)  jsModule  A js-module entry from PluginInfo class to generate metadata for
 */
function ModuleMetadata (pluginId, jsModule) {

    if (!pluginId) throw new TypeError('pluginId argument must be a valid plugin id');
    if (!jsModule.src && !jsModule.name) throw new TypeError('jsModule argument must contain src or/and name properties');

    this.id = pluginId + '.' + (jsModule.name || jsModule.src.match(/([^\/]+)\.js/)[1]); /* eslint no-useless-escape: 0 */
    this.file = ['plugins', pluginId, jsModule.src].join('/');
    this.pluginId = pluginId;

    if (jsModule.clobbers && jsModule.clobbers.length > 0) {
        this.clobbers = jsModule.clobbers.map(function (o) { return o.target; });
    }
    if (jsModule.merges && jsModule.merges.length > 0) {
        this.merges = jsModule.merges.map(function (o) { return o.target; });
    }
    if (jsModule.runs) {
        this.runs = true;
    }
}

module.exports = PlatformJson;
