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

/*
 * This module deals with shared configuration / dependency "stuff". That is:
 * - XML configuration files such as config.xml, AndroidManifest.xml or WMAppManifest.xml.
 * - plist files in iOS
 * Essentially, any type of shared resources that we need to handle with awareness
 * of how potentially multiple plugins depend on a single shared resource, should be
 * handled in this module.
 *
 * The implementation uses an object as a hash table, with "leaves" of the table tracking
 * reference counts.
 */

var path = require('path');
var et = require('elementtree');
var ConfigKeeper = require('./ConfigKeeper');
var events = require('../events');

var mungeutil = require('./munge-util');
var xml_helpers = require('../util/xml-helpers');

exports.PlatformMunger = PlatformMunger;

exports.process = function (plugins_dir, project_dir, platform, platformJson, pluginInfoProvider) {
    var munger = new PlatformMunger(platform, project_dir, platformJson, pluginInfoProvider);
    munger.process(plugins_dir);
    munger.save_all();
};

/******************************************************************************
* PlatformMunger class
*
* Can deal with config file of a single project.
* Parsed config files are cached in a ConfigKeeper object.
******************************************************************************/
function PlatformMunger (platform, project_dir, platformJson, pluginInfoProvider) {
    this.platform = platform;
    this.project_dir = project_dir;
    this.config_keeper = new ConfigKeeper(project_dir);
    this.platformJson = platformJson;
    this.pluginInfoProvider = pluginInfoProvider;
}

// Write out all unsaved files.
PlatformMunger.prototype.save_all = PlatformMunger_save_all;
function PlatformMunger_save_all () {
    this.config_keeper.save_all();
    this.platformJson.save();
}

// Apply a munge object to a single config file.
// The remove parameter tells whether to add the change or remove it.
PlatformMunger.prototype.apply_file_munge = PlatformMunger_apply_file_munge;
function PlatformMunger_apply_file_munge (file, munge, remove) {
    var self = this;

    for (var selector in munge.parents) {
        for (var xml_child in munge.parents[selector]) {
            // this xml child is new, graft it (only if config file exists)
            var config_file = self.config_keeper.get(self.project_dir, self.platform, file);
            if (config_file.exists) {
                if (remove) config_file.prune_child(selector, munge.parents[selector][xml_child]);
                else config_file.graft_child(selector, munge.parents[selector][xml_child]);
            } else {
                events.emit('warn', 'config file ' + file + ' requested for changes not found at ' + config_file.filepath + ', ignoring');
            }
        }
    }
}

PlatformMunger.prototype.remove_plugin_changes = remove_plugin_changes;
function remove_plugin_changes (pluginInfo, is_top_level) {
    var self = this;
    var platform_config = self.platformJson.root;
    var plugin_vars = is_top_level
        ? platform_config.installed_plugins[pluginInfo.id]
        : platform_config.dependent_plugins[pluginInfo.id];
    var edit_config_changes = null;
    if (pluginInfo.getEditConfigs) {
        edit_config_changes = pluginInfo.getEditConfigs(self.platform);
    }

    // get config munge, aka how did this plugin change various config files
    var config_munge = self.generate_plugin_config_munge(pluginInfo, plugin_vars, edit_config_changes);
    // global munge looks at all plugins' changes to config files
    var global_munge = platform_config.config_munge;
    var munge = mungeutil.decrement_munge(global_munge, config_munge);

    for (var file in munge.files) {
        self.apply_file_munge(file, munge.files[file], /* remove = */ true);
    }

    // Remove from installed_plugins
    self.platformJson.removePlugin(pluginInfo.id, is_top_level);
    return self;
}

PlatformMunger.prototype.add_plugin_changes = add_plugin_changes;
function add_plugin_changes (pluginInfo, plugin_vars, is_top_level, should_increment, plugin_force) {
    var self = this;
    var platform_config = self.platformJson.root;

    var edit_config_changes = null;
    if (pluginInfo.getEditConfigs) {
        edit_config_changes = pluginInfo.getEditConfigs(self.platform);
    }

    var config_munge;

    if (!edit_config_changes || edit_config_changes.length === 0) {
        // get config munge, aka how should this plugin change various config files
        config_munge = self.generate_plugin_config_munge(pluginInfo, plugin_vars);
    } else {
        var isConflictingInfo = is_conflicting(edit_config_changes, platform_config.config_munge, self, plugin_force);

        if (isConflictingInfo.conflictWithConfigxml) {
            throw new Error(pluginInfo.id +
                ' cannot be added. <edit-config> changes in this plugin conflicts with <edit-config> changes in config.xml. Conflicts must be resolved before plugin can be added.');
        }
        if (plugin_force) {
            events.emit('warn', '--force is used. edit-config will overwrite conflicts if any. Conflicting plugins may not work as expected.');

            // remove conflicting munges
            var conflict_munge = mungeutil.decrement_munge(platform_config.config_munge, isConflictingInfo.conflictingMunge);
            for (var conflict_file in conflict_munge.files) {
                self.apply_file_munge(conflict_file, conflict_munge.files[conflict_file], /* remove = */ true);
            }

            // force add new munges
            config_munge = self.generate_plugin_config_munge(pluginInfo, plugin_vars, edit_config_changes);
        } else if (isConflictingInfo.conflictFound) {
            throw new Error('There was a conflict trying to modify attributes with <edit-config> in plugin ' + pluginInfo.id +
            '. The conflicting plugin, ' + isConflictingInfo.conflictingPlugin + ', already modified the same attributes. The conflict must be resolved before ' +
            pluginInfo.id + ' can be added. You may use --force to add the plugin and overwrite the conflicting attributes.');
        } else {
            // no conflicts, will handle edit-config
            config_munge = self.generate_plugin_config_munge(pluginInfo, plugin_vars, edit_config_changes);
        }
    }

    self = munge_helper(should_increment, self, platform_config, config_munge);

    // Move to installed/dependent_plugins
    self.platformJson.addPlugin(pluginInfo.id, plugin_vars || {}, is_top_level);
    return self;
}

// Handle edit-config changes from config.xml
PlatformMunger.prototype.add_config_changes = add_config_changes;
function add_config_changes (config, should_increment) {
    var self = this;
    var platform_config = self.platformJson.root;

    var config_munge;
    var changes = [];

    if (config.getEditConfigs) {
        var edit_config_changes = config.getEditConfigs(self.platform);
        if (edit_config_changes) {
            changes = changes.concat(edit_config_changes);
        }
    }

    if (config.getConfigFiles) {
        var config_files_changes = config.getConfigFiles(self.platform);
        if (config_files_changes) {
            changes = changes.concat(config_files_changes);
        }
    }

    if (changes && changes.length > 0) {
        var isConflictingInfo = is_conflicting(changes, platform_config.config_munge, self, true /* always force overwrite other edit-config */);
        if (isConflictingInfo.conflictFound) {
            var conflict_munge;
            var conflict_file;

            if (Object.keys(isConflictingInfo.configxmlMunge.files).length !== 0) {
                // silently remove conflicting config.xml munges so new munges can be added
                conflict_munge = mungeutil.decrement_munge(platform_config.config_munge, isConflictingInfo.configxmlMunge);
                for (conflict_file in conflict_munge.files) {
                    self.apply_file_munge(conflict_file, conflict_munge.files[conflict_file], /* remove = */ true);
                }
            }
            if (Object.keys(isConflictingInfo.conflictingMunge.files).length !== 0) {
                events.emit('warn', 'Conflict found, edit-config changes from config.xml will overwrite plugin.xml changes');

                // remove conflicting plugin.xml munges
                conflict_munge = mungeutil.decrement_munge(platform_config.config_munge, isConflictingInfo.conflictingMunge);
                for (conflict_file in conflict_munge.files) {
                    self.apply_file_munge(conflict_file, conflict_munge.files[conflict_file], /* remove = */ true);
                }
            }
        }
    }

    // Add config.xml edit-config and config-file munges
    config_munge = self.generate_config_xml_munge(config, changes, 'config.xml');
    self = munge_helper(should_increment, self, platform_config, config_munge);

    // Move to installed/dependent_plugins
    return self;
}

function munge_helper (should_increment, self, platform_config, config_munge) {
    // global munge looks at all changes to config files

    // TODO: The should_increment param is only used by cordova-cli and is going away soon.
    // If should_increment is set to false, avoid modifying the global_munge (use clone)
    // and apply the entire config_munge because it's already a proper subset of the global_munge.
    var munge, global_munge;
    if (should_increment) {
        global_munge = platform_config.config_munge;
        munge = mungeutil.increment_munge(global_munge, config_munge);
    } else {
        global_munge = mungeutil.clone_munge(platform_config.config_munge);
        munge = config_munge;
    }

    for (var file in munge.files) {
        self.apply_file_munge(file, munge.files[file]);
    }

    return self;
}

// Load the global munge from platform json and apply all of it.
// Used by cordova prepare to re-generate some config file from platform
// defaults and the global munge.
PlatformMunger.prototype.reapply_global_munge = reapply_global_munge;
function reapply_global_munge () {
    var self = this;

    var platform_config = self.platformJson.root;
    var global_munge = platform_config.config_munge;
    for (var file in global_munge.files) {
        self.apply_file_munge(file, global_munge.files[file]);
    }

    return self;
}

// generate_plugin_config_munge
// Generate the munge object from config.xml
PlatformMunger.prototype.generate_config_xml_munge = generate_config_xml_munge;
function generate_config_xml_munge (config, config_changes, type) {
    var munge = { files: {} };
    var id;

    if (!config_changes) {
        return munge;
    }

    if (type === 'config.xml') {
        id = type;
    } else {
        id = config.id;
    }

    config_changes.forEach(function (change) {
        change.xmls.forEach(function (xml) {
            // 1. stringify each xml
            var stringified = (new et.ElementTree(xml)).write({ xml_declaration: false });
            // 2. add into munge
            if (change.mode) {
                mungeutil.deep_add(munge, change.file, change.target, { xml: stringified, count: 1, mode: change.mode, id: id });
            } else {
                mungeutil.deep_add(munge, change.target, change.parent, { xml: stringified, count: 1, after: change.after });
            }
        });
    });
    return munge;
}

// generate_plugin_config_munge
// Generate the munge object from plugin.xml + vars
PlatformMunger.prototype.generate_plugin_config_munge = generate_plugin_config_munge;
function generate_plugin_config_munge (pluginInfo, vars, edit_config_changes) {
    var self = this;

    vars = vars || {};
    var munge = { files: {} };
    var changes = pluginInfo.getConfigFiles(self.platform);

    if (edit_config_changes) {
        Array.prototype.push.apply(changes, edit_config_changes);
    }

    changes.forEach(function (change) {
        change.xmls.forEach(function (xml) {
            // 1. stringify each xml
            var stringified = (new et.ElementTree(xml)).write({ xml_declaration: false });
            // interp vars
            if (vars) {
                Object.keys(vars).forEach(function (key) {
                    var regExp = new RegExp('\\$' + key, 'g');
                    stringified = stringified.replace(regExp, vars[key]);
                });
            }
            // 2. add into munge
            if (change.mode) {
                if (change.mode !== 'remove') {
                    mungeutil.deep_add(munge, change.file, change.target, { xml: stringified, count: 1, mode: change.mode, plugin: pluginInfo.id });
                }
            } else {
                mungeutil.deep_add(munge, change.target, change.parent, { xml: stringified, count: 1, after: change.after });
            }
        });
    });
    return munge;
}

function is_conflicting (editchanges, config_munge, self, force) {
    var files = config_munge.files;
    var conflictFound = false;
    var conflictWithConfigxml = false;
    var conflictingMunge = { files: {} };
    var configxmlMunge = { files: {} };
    var conflictingParent;
    var conflictingPlugin;

    editchanges.forEach(function (editchange) {
        if (files[editchange.file]) {
            var parents = files[editchange.file].parents;
            var target = parents[editchange.target];

            // Check if the edit target will resolve to an existing target
            if (!target || target.length === 0) {
                var file_xml = self.config_keeper.get(self.project_dir, self.platform, editchange.file).data;
                var resolveEditTarget = xml_helpers.resolveParent(file_xml, editchange.target);
                var resolveTarget;

                if (resolveEditTarget) {
                    for (var parent in parents) {
                        resolveTarget = xml_helpers.resolveParent(file_xml, parent);
                        if (resolveEditTarget === resolveTarget) {
                            conflictingParent = parent;
                            target = parents[parent];
                            break;
                        }
                    }
                }
            } else {
                conflictingParent = editchange.target;
            }

            if (target && target.length !== 0) {
                // conflict has been found
                conflictFound = true;

                if (editchange.id === 'config.xml') {
                    if (target[0].id === 'config.xml') {
                        // Keep track of config.xml/config.xml edit-config conflicts
                        mungeutil.deep_add(configxmlMunge, editchange.file, conflictingParent, target[0]);
                    } else {
                        // Keep track of config.xml x plugin.xml edit-config conflicts
                        mungeutil.deep_add(conflictingMunge, editchange.file, conflictingParent, target[0]);
                    }
                } else {
                    if (target[0].id === 'config.xml') {
                        // plugin.xml cannot overwrite config.xml changes even if --force is used
                        conflictWithConfigxml = true;
                        return;
                    }

                    if (force) {
                        // Need to find all conflicts when --force is used, track conflicting munges
                        mungeutil.deep_add(conflictingMunge, editchange.file, conflictingParent, target[0]);
                    } else {
                        // plugin cannot overwrite other plugin changes without --force
                        conflictingPlugin = target[0].plugin;
                    }
                }
            }
        }
    });

    return { conflictFound: conflictFound,
        conflictingPlugin: conflictingPlugin,
        conflictingMunge: conflictingMunge,
        configxmlMunge: configxmlMunge,
        conflictWithConfigxml: conflictWithConfigxml
    };
}

// Go over the prepare queue and apply the config munges for each plugin
// that has been (un)installed.
PlatformMunger.prototype.process = PlatformMunger_process;
function PlatformMunger_process (plugins_dir) {
    var self = this;
    var platform_config = self.platformJson.root;

    // Uninstallation first
    platform_config.prepare_queue.uninstalled.forEach(function (u) {
        var pluginInfo = self.pluginInfoProvider.get(path.join(plugins_dir, u.plugin));
        self.remove_plugin_changes(pluginInfo, u.topLevel);
    });

    // Now handle installation
    platform_config.prepare_queue.installed.forEach(function (u) {
        var pluginInfo = self.pluginInfoProvider.get(path.join(plugins_dir, u.plugin));
        self.add_plugin_changes(pluginInfo, u.vars, u.topLevel, true, u.force);
    });

    // Empty out installed/ uninstalled queues.
    platform_config.prepare_queue.uninstalled = [];
    platform_config.prepare_queue.installed = [];
}
/** ** END of PlatformMunger ****/
