/**
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 file is found by cordova-lib when you attempt to
    'cordova platform add PATH' where path is this repo.
*/

var shell = require('shelljs');
var path = require('path');
var fs = require('fs');

var cdvcmn = require('cordova-common');
var CordovaLogger = cdvcmn.CordovaLogger;
var ConfigParser = cdvcmn.ConfigParser;
var ActionStack = cdvcmn.ActionStack;
var selfEvents = cdvcmn.events;
var xmlHelpers = cdvcmn.xmlHelpers;
var PlatformJson = cdvcmn.PlatformJson;
var PlatformMunger = cdvcmn.ConfigChanges.PlatformMunger;
var PluginInfoProvider = cdvcmn.PluginInfoProvider;

var BrowserParser = require('./browser_parser');
var PLATFORM_NAME = 'browser';

function setupEvents (externalEventEmitter) {
    if (externalEventEmitter) {
        // This will make the platform internal events visible outside
        selfEvents.forwardEventsTo(externalEventEmitter);
        return externalEventEmitter;
    }

    // There is no logger if external emitter is not present,
    // so attach a console logger
    CordovaLogger.get().subscribe(selfEvents);
    return selfEvents;
}

function Api (platform, platformRootDir, events) {
    this.platform = platform || PLATFORM_NAME;

    // MyApp/platforms/browser
    this.root = path.resolve(__dirname, '..');
    this.events = setupEvents(events);
    this.parser = new BrowserParser(this.root);
    this._handler = require('./browser_handler');

    this.locations = {
        platformRootDir: platformRootDir,
        root: this.root,
        www: path.join(this.root, 'www'),
        res: path.join(this.root, 'res'),
        platformWww: path.join(this.root, 'platform_www'),
        configXml: path.join(this.root, 'config.xml'),
        defaultConfigXml: path.join(this.root, 'cordova/defaults.xml'),
        build: path.join(this.root, 'build'),
        // NOTE: Due to platformApi spec we need to return relative paths here
        cordovaJs: 'bin/templates/project/assets/www/cordova.js',
        cordovaJsSrc: 'cordova-js-src'
    };

    this._platformJson = PlatformJson.load(this.root, platform);
    this._pluginInfoProvider = new PluginInfoProvider();
    this._munger = new PlatformMunger(platform, this.root, this._platformJson, this._pluginInfoProvider);
}

Api.createPlatform = function (dest, config, options, events) {
    var creator = require('../../lib/create');
    events = setupEvents(events);

    var name = 'HelloCordova';
    var id = 'io.cordova.hellocordova';
    if (config) {
        name = config.name();
        id = config.packageName();
    }

    var result;
    try {
        // we create the project using our scripts in this platform
        result = creator.createProject(dest, id, name, options)
            .then(function () {
                // after platform is created we return Api instance based on new Api.js location
                // Api.js has been copied to the new project
                // This is required to correctly resolve paths in the future api calls
                var PlatformApi = require(path.resolve(dest, 'cordova/Api'));
                return new PlatformApi('browser', dest, events);
            });
    } catch (e) {
        events.emit('error', 'createPlatform is not callable from the browser project API.');
        throw (e);
    }
    return result;
};

Api.updatePlatform = function (dest, options, events) {
    // console.log("test-platform:Api:updatePlatform");
    // todo?: create projectInstance and fulfill promise with it.
    return Promise.resolve();
};

Api.prototype.getPlatformInfo = function () {
    // console.log("browser-platform:Api:getPlatformInfo");
    // return PlatformInfo object
    return {
        locations: this.locations,
        root: this.root,
        name: this.platform,
        version: { version: '1.0.0' }, // um, todo!
        projectConfig: this.config
    };
};

Api.prototype.prepare = function (cordovaProject, options) {
    // First cleanup current config and merge project's one into own
    var defaultConfigPath = path.join(this.locations.platformRootDir, 'cordova',
        'defaults.xml');
    var ownConfigPath = this.locations.configXml;
    var sourceCfg = cordovaProject.projectConfig;

    // If defaults.xml is present, overwrite platform config.xml with it.
    // Otherwise save whatever is there as defaults so it can be
    // restored or copy project config into platform if none exists.
    if (fs.existsSync(defaultConfigPath)) {
        this.events.emit('verbose', 'Generating config.xml from defaults for platform "' + this.platform + '"');
        shell.cp('-f', defaultConfigPath, ownConfigPath);
    } else if (fs.existsSync(ownConfigPath)) {
        this.events.emit('verbose', 'Generating defaults.xml from own config.xml for platform "' + this.platform + '"');
        shell.cp('-f', ownConfigPath, defaultConfigPath);
    } else {
        this.events.emit('verbose', 'case 3"' + this.platform + '"');
        shell.cp('-f', sourceCfg.path, ownConfigPath);
    }

    // merge our configs
    this.config = new ConfigParser(ownConfigPath);
    xmlHelpers.mergeXml(cordovaProject.projectConfig.doc.getroot(),
        this.config.doc.getroot(),
        this.platform, true);
    this.config.write();

    // Update own www dir with project's www assets and plugins' assets and js-files
    this.parser.update_www(cordovaProject, options);

    // Copy or Create manifest.json
    // todo: move this to a manifest helper module
    // output path
    var manifestPath = path.join(this.locations.www, 'manifest.json');
    var srcManifestPath = path.join(cordovaProject.locations.www, 'manifest.json');
    if (fs.existsSync(srcManifestPath)) {
        // just blindly copy it to our output/www
        // todo: validate it? ensure all properties we expect exist?
        this.events.emit('verbose', 'copying ' + srcManifestPath + ' => ' + manifestPath);
        shell.cp('-f', srcManifestPath, manifestPath);
    } else {
        var manifestJson = {
            background_color: '#FFF',
            display: 'standalone'
        };
        if (this.config) {
            if (this.config.name()) {
                manifestJson.name = this.config.name();
            }
            if (this.config.shortName()) {
                manifestJson.short_name = this.config.shortName();
            }
            if (this.config.packageName()) {
                manifestJson.version = this.config.packageName();
            }
            if (this.config.description()) {
                manifestJson.description = this.config.description();
            }
            if (this.config.author()) {
                manifestJson.author = this.config.author();
            }
            // icons
            var icons = this.config.getStaticResources('browser', 'icon');
            var manifestIcons = icons.map(function (icon) {
                // given a tag like this :
                // <icon src="res/ios/icon.png" width="57" height="57" density="mdpi" />
                /* configParser returns icons that look like this :
                {   src: 'res/ios/icon.png',
                    target: undefined,
                    density: 'mdpi',
                    platform: null,
                    width: 57,
                    height: 57
                } ******/
                /* manifest expects them to be like this :
                {   "src": "images/touch/icon-128x128.png",
                    "type": "image/png",
                    "sizes": "128x128"
                } ******/
                // ?Is it worth looking at file extentions?
                return {
                    src: icon.src,
                    type: 'image/png',
                    sizes: (icon.width + 'x' + icon.height)
                };
            });
            manifestJson.icons = manifestIcons;

            // orientation
            // <preference name="Orientation" value="landscape" />
            var oriPref = this.config.getGlobalPreference('Orientation');
            if (oriPref) {
                // if it's a supported value, use it
                if (['landscape', 'portrait'].indexOf(oriPref) > -1) {
                    manifestJson.orientation = oriPref;
                } else { // anything else maps to 'any'
                    manifestJson.orientation = 'any';
                }
            }

            // get start_url
            var contentNode = this.config.doc.find('content') || { attrib: { src: 'index.html' } }; // sensible default
            manifestJson.start_url = contentNode.attrib.src;

            // now we get some values from start_url page ...
            var startUrlPath = path.join(cordovaProject.locations.www, manifestJson.start_url);
            if (fs.existsSync(startUrlPath)) {
                var contents = fs.readFileSync(startUrlPath, 'utf-8');
                // matches <meta name="theme-color" content="#FF0044">
                var themeColorRegex = /<meta(?=[^>]*name="theme-color")\s[^>]*content="([^>]*)"/i;
                var result = themeColorRegex.exec(contents);
                var themeColor;
                if (result && result.length >= 2) {
                    themeColor = result[1];
                } else { // see if there is a preference in config.xml
                    // <preference name="StatusBarBackgroundColor" value="#000000" />
                    themeColor = this.config.getGlobalPreference('StatusBarBackgroundColor');
                }
                if (themeColor) {
                    manifestJson.theme_color = themeColor;
                }
            }
        }
        fs.writeFileSync(manifestPath, JSON.stringify(manifestJson, null, 2), 'utf8');
    }

    // update project according to config.xml changes.
    return this.parser.update_project(this.config, options);
};

Api.prototype.addPlugin = function (pluginInfo, installOptions) {
    // console.log(new Error().stack);
    if (!pluginInfo) {
        return Promise.reject(new Error('The parameter is incorrect. The first parameter ' +
            'should be valid PluginInfo instance'));
    }

    installOptions = installOptions || {};
    installOptions.variables = installOptions.variables || {};
    // CB-10108 platformVersion option is required for proper plugin installation
    installOptions.platformVersion = installOptions.platformVersion ||
        this.getPlatformInfo().version;

    var self = this;
    var actions = new ActionStack();
    var projectFile = this._handler.parseProjectFile && this._handler.parseProjectFile(this.root);

    // gather all files needs to be handled during install
    pluginInfo.getFilesAndFrameworks(this.platform)
        .concat(pluginInfo.getAssets(this.platform))
        .concat(pluginInfo.getJsModules(this.platform))
        .forEach(function (item) {
            actions.push(actions.createAction(
                self._getInstaller(item.itemType),
                [item, pluginInfo.dir, pluginInfo.id, installOptions, projectFile],
                self._getUninstaller(item.itemType),
                [item, pluginInfo.dir, pluginInfo.id, installOptions, projectFile]));
        });

    // run through the action stack
    return actions.process(this.platform, this.root)
        .then(function () {
            if (projectFile) {
                projectFile.write();
            }

            // Add PACKAGE_NAME variable into vars
            if (!installOptions.variables.PACKAGE_NAME) {
                installOptions.variables.PACKAGE_NAME = self._handler.package_name(self.root);
            }

            self._munger
                // Ignore passed `is_top_level` option since platform itself doesn't know
                // anything about managing dependencies - it's responsibility of caller.
                .add_plugin_changes(pluginInfo, installOptions.variables, /* is_top_level= */true, /* should_increment= */true)
                .save_all();

            var targetDir = installOptions.usePlatformWww
                ? self.getPlatformInfo().locations.platformWww
                : self.getPlatformInfo().locations.www;

            self._addModulesInfo(pluginInfo, targetDir);
        });
};

Api.prototype.removePlugin = function (plugin, uninstallOptions) {
    // console.log("NotImplemented :: browser-platform:Api:removePlugin ",plugin, uninstallOptions);

    uninstallOptions = uninstallOptions || {};
    // CB-10108 platformVersion option is required for proper plugin installation
    uninstallOptions.platformVersion = uninstallOptions.platformVersion ||
        this.getPlatformInfo().version;

    var self = this;
    var actions = new ActionStack();
    var projectFile = this._handler.parseProjectFile && this._handler.parseProjectFile(this.root);

    // queue up plugin files
    plugin.getFilesAndFrameworks(this.platform)
        .concat(plugin.getAssets(this.platform))
        .concat(plugin.getJsModules(this.platform))
        .forEach(function (item) {
            actions.push(actions.createAction(
                self._getUninstaller(item.itemType), [item, plugin.dir, plugin.id, uninstallOptions, projectFile],
                self._getInstaller(item.itemType), [item, plugin.dir, plugin.id, uninstallOptions, projectFile]));
        });

    // run through the action stack
    return actions.process(this.platform, this.root)
        .then(function () {
            if (projectFile) {
                projectFile.write();
            }

            self._munger
                // Ignore passed `is_top_level` option since platform itself doesn't know
                // anything about managing dependencies - it's responsibility of caller.
                .remove_plugin_changes(plugin, /* is_top_level= */true)
                .save_all();

            var targetDir = uninstallOptions.usePlatformWww
                ? self.getPlatformInfo().locations.platformWww
                : self.getPlatformInfo().locations.www;

            self._removeModulesInfo(plugin, targetDir);
            // Remove stale plugin directory
            // TODO: this should be done by plugin files uninstaller
            shell.rm('-rf', path.resolve(self.root, 'Plugins', plugin.id));
        });
};

Api.prototype._getInstaller = function (type) {
    var self = this;
    return function (item, plugin_dir, plugin_id, options, project) {
        var installer = self._handler[type];

        if (!installer) {
            console.log('unrecognized type ' + type);
        } else {
            var wwwDest = options.usePlatformWww
                ? self.getPlatformInfo().locations.platformWww
                : self._handler.www_dir(self.root);

            if (type === 'asset') {
                installer.install(item, plugin_dir, wwwDest);
            } else if (type === 'js-module') {
                installer.install(item, plugin_dir, plugin_id, wwwDest);
            } else {
                installer.install(item, plugin_dir, self.root, plugin_id, options, project);
            }
        }
    };
};

Api.prototype._getUninstaller = function (type) {
    var self = this;
    return function (item, plugin_dir, plugin_id, options, project) {
        var installer = self._handler[type];

        if (!installer) {
            console.log('browser plugin uninstall: unrecognized type, skipping : ' + type);
        } else {
            var wwwDest = options.usePlatformWww
                ? self.getPlatformInfo().locations.platformWww
                : self._handler.www_dir(self.root);

            if (['asset', 'js-module'].indexOf(type) > -1) {
                return installer.uninstall(item, wwwDest, plugin_id);
            } else {
                return installer.uninstall(item, self.root, plugin_id, options, project);
            }
        }
    };
};

/**
 * Removes the specified modules from list of installed modules and updates
 *   platform_json and cordova_plugins.js on disk.
 *
 * @param   {PluginInfo}  plugin  PluginInfo instance for plugin, which modules
 *   needs to be added.
 * @param   {String}  targetDir  The directory, where updated cordova_plugins.js
 *   should be written to.
 */
Api.prototype._addModulesInfo = function (plugin, targetDir) {
    var installedModules = this._platformJson.root.modules || [];

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

    var modulesToInstall = plugin.getJsModules(this.platform)
        .filter(function (moduleToInstall) {
            return installedPaths.indexOf(moduleToInstall.file) === -1;
        }).map(function (moduleToInstall) {
            var moduleName = plugin.id + '.' + (moduleToInstall.name || moduleToInstall.src.match(/([^/]+)\.js/)[1]);
            var obj = {
                file: ['plugins', plugin.id, moduleToInstall.src].join('/'),
                id: moduleName,
                pluginId: plugin.id
            };
            if (moduleToInstall.clobbers.length > 0) {
                obj.clobbers = moduleToInstall.clobbers.map(function (o) { return o.target; });
            }
            if (moduleToInstall.merges.length > 0) {
                obj.merges = moduleToInstall.merges.map(function (o) { return o.target; });
            }
            if (moduleToInstall.runs) {
                obj.runs = true;
            }

            return obj;
        });

    this._platformJson.root.modules = installedModules.concat(modulesToInstall);
    if (!this._platformJson.root.plugin_metadata) {
        this._platformJson.root.plugin_metadata = {};
    }
    this._platformJson.root.plugin_metadata[plugin.id] = plugin.version;

    this._writePluginModules(targetDir);
    this._platformJson.save();
};
/**
 * Fetches all installed modules, generates cordova_plugins contents and writes
 *   it to file.
 *
 * @param   {String}  targetDir  Directory, where write cordova_plugins.js to.
 *   Ususally it is either <platform>/www or <platform>/platform_www
 *   directories.
 */
Api.prototype._writePluginModules = function (targetDir) {
    // Write out moduleObjects as JSON wrapped in a cordova module to cordova_plugins.js
    var final_contents = 'cordova.define(\'cordova/plugin_list\', function(require, exports, module) {\n';
    final_contents += 'module.exports = ' + JSON.stringify(this._platformJson.root.modules, null, '    ') + ';\n';
    final_contents += 'module.exports.metadata = \n';
    final_contents += '// TOP OF METADATA\n';
    final_contents += JSON.stringify(this._platformJson.root.plugin_metadata || {}, null, '    ') + '\n';
    final_contents += '// BOTTOM OF METADATA\n';
    final_contents += '});'; // Close cordova.define.

    shell.mkdir('-p', targetDir);
    fs.writeFileSync(path.join(targetDir, 'cordova_plugins.js'), final_contents, 'utf-8');
};

/**
 * Removes the specified modules from list of installed modules and updates
 *   platform_json and cordova_plugins.js on disk.
 *
 * @param   {PluginInfo}  plugin  PluginInfo instance for plugin, which modules
 *   needs to be removed.
 * @param   {String}  targetDir  The directory, where updated cordova_plugins.js
 *   should be written to.
 */
Api.prototype._removeModulesInfo = function (plugin, targetDir) {
    var installedModules = this._platformJson.root.modules || [];
    var modulesToRemove = plugin.getJsModules(this.platform)
        .map(function (jsModule) {
            return ['plugins', plugin.id, jsModule.src].join('/');
        });

    var updatedModules = installedModules
        .filter(function (installedModule) {
            return (modulesToRemove.indexOf(installedModule.file) === -1);
        });

    this._platformJson.root.modules = updatedModules;
    if (this._platformJson.root.plugin_metadata) {
        delete this._platformJson.root.plugin_metadata[plugin.id];
    }

    this._writePluginModules(targetDir);
    this._platformJson.save();
};

Api.prototype.build = function (buildOptions) {
    var self = this;
    return require('./lib/check_reqs').run()
        .then(function () {
            return require('./lib/build').run.call(self, buildOptions);
        });
};

Api.prototype.run = function (runOptions) {
    return require('./lib/run').run(runOptions);
};

Api.prototype.clean = function (cleanOptions) {
    return require('./lib/clean').run(cleanOptions);
};

Api.prototype.requirements = function () {
    return require('./lib/check_reqs').run();
};

module.exports = Api;
