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