/**
    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.
*/
var cordova_util  = require('./util'),
    util          = require('util'),
    fs            = require('fs'),
    shell         = require('shelljs'),
    path          = require('path'),
    shell         = require('shelljs'),
    platforms     = require('../platforms'),
    config_parser = require('./config_parser'),
    n             = require('ncallbacks'),
    hooker        = require('./hooker'),
    events        = require('./events'),
    plugin_parser = require('./plugin_parser'),
    ls            = fs.readdirSync,
    plugman       = require('plugman');

module.exports = function plugin(command, targets, callback) {
    var projectRoot = cordova_util.isCordova(process.cwd());

    if (!projectRoot) {
        var err = new Error('Current working directory is not a Cordova-based project.');
        if (callback) callback(err);
        else throw err;
        return;
    }
    if (arguments.length === 0) command = 'ls';

    var hooks = new hooker(projectRoot);

    // Grab config info for the project
    var xml = cordova_util.projectConfig(projectRoot);
    var cfg = new config_parser(xml);
    var platformList = cordova_util.listPlatforms(projectRoot);

    // Massage plugin name(s) / path(s)
    var pluginPath, plugins;
    pluginPath = path.join(projectRoot, 'plugins');
    plugins = cordova_util.findPlugins(pluginPath);
    if (targets && !(targets instanceof Array)) {
        targets = [targets];
    }
    var opts = {
        plugins:targets
    };

    switch(command) {
        case 'ls':
        case 'list':
            hooks.fire('before_plugin_ls', function(err) {
                if (err) {
                    if (callback) callback(err);
                    else throw err;
                } else {
                    events.emit('results', (plugins.length ? plugins : 'No plugins added. Use `cordova plugin add <plugin>`.'));
                    hooks.fire('after_plugin_ls', function(err) {
                        if (err) {
                            if (callback) callback(err);
                            else throw err;
                        }
                    });
                }
            });
            break;
        case 'add':
            var end = n(targets.length, function() {
                hooks.fire('after_plugin_add', opts, function(err) {
                    if (err) {
                        if (callback) callback(err);
                        else throw err;
                    } else {
                        if (callback) callback();
                    }
                });
            });
            hooks.fire('before_plugin_add', opts, function(err) {
                if (err) {
                    if (callback) callback(err);
                    else throw err;
                } else {
                    targets.forEach(function(target, index) {
                        var pluginsDir = path.join(projectRoot, 'plugins');

                        if (target[target.length - 1] == path.sep) {
                            target = target.substring(0, target.length - 1);
                        }

                        // Fetch the plugin first.
                        events.emit('log', 'Calling plugman.fetch on plugin "' + target + '"');
                        plugman.fetch(target, pluginsDir, {}, function(err, dir) {
                            if (err) {
                                var err = new Error('Error fetching plugin: ' + err);
                                if (callback) callback(err);
                                else throw err;
                            } else {
                                // Iterate over all platforms in the project and install the plugin.
                                platformList.forEach(function(platform) {
                                    var platformRoot = path.join(projectRoot, 'platforms', platform);
                                    var parser = new platforms[platform].parser(platformRoot);
                                    // TODO: unify use of blackberry in cli vs blackberry10 in plugman
                                    events.emit('log', 'Calling plugman.install on plugin "' + dir + '" for platform "' + platform + '"');
                                    plugman.install((platform=='blackberry'?'blackberry10':platform), platformRoot,
                                                    path.basename(dir), pluginsDir, { www_dir: parser.staging_dir() });
                                });
                                end();
                            }
                        });
                    });
                }
            });
            break;
        case 'rm':
        case 'remove':
            var end = n(targets.length, function() {
                hooks.fire('after_plugin_rm', opts, function(err) {
                    if (err) {
                        if (callback) callback(err);
                        else throw err;
                    } else {
                        if (callback) callback();
                    }
                });
            });
            hooks.fire('before_plugin_rm', opts, function(err) {
                if (err) {
                    if (callback) callback(err);
                    else throw err;
                } else {
                    targets.forEach(function(target, index) {
                        // Check if we have the plugin.
                        if (plugins.indexOf(target) > -1) {
                            var targetPath = path.join(pluginPath, target);
                            // Check if there is at least one match between plugin
                            // supported platforms and app platforms
                            var pluginXml = new plugin_parser(path.join(targetPath, 'plugin.xml'));
                            var intersection = pluginXml.platforms.filter(function(e) {
                                if (platformList.indexOf(e) == -1) return false;
                                else return true;
                            });

                            // Iterate over all the common platforms between the plugin
                            // and the app, and uninstall.
                            // If this is a web-only plugin with no platform tags, this step
                            // is not needed and we just --remove the plugin below.
                            intersection.forEach(function(platform) {
                                var platformRoot = path.join(projectRoot, 'platforms', platform);
                                var parser = new platforms[platform].parser(platformRoot);
                                events.emit('log', 'Calling plugman.uninstall on plugin "' + target + '" for platform "' + platform + '"');
                                plugman.uninstall(platform, platformRoot, target, path.join(projectRoot, 'plugins'), { www_dir: parser.staging_dir() });
                            });
                            end();
                        } else {
                            var err = new Error('Plugin "' + target + '" not added to project.');
                            if (callback) callback(err);
                            else throw err;
                            return;
                        }
                    });
                }
            });
            break;
        default:
            var err = new Error('Unrecognized command "' + command + '". Use either `add`, `remove`, or `list`.');
            if (callback) callback(err);
            else throw err;
    }
};
