/**
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.locations.www);

    // 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('/'), /* eslint no-useless-escape : 0 */
                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;
