/*
 *  Copyright 2012 Research In Motion Limited.
 *
 * Licensed 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.
 */
/*jshint sub:true*/
var fs = require("fs"),
    util = require('util'),
    xml2js = require('xml2js'),
    packagerUtils = require('./packager-utils'),
    check = require('validator').check,
    sanitize = require('validator').sanitize,
    localize = require("./localize"),
    logger = require("./logger"),
    fileManager = require("./file-manager"),
    utils = require("./packager-utils"),
    i18nMgr = require("./i18n-manager"),
    et = require("elementtree"),
    _config_doc,
    _self,
    _predefinedFeatures;

//This function will convert a wc3 paramObj with a list of
//<param name="" value=""> elements into a single object
function processParamObj(paramObj) {
    var processedObj = {},
        attribs,
        paramName,
        paramValue;

    if (paramObj) {
        //Convert to array for single param entries where only an object is created
        if (!Array.isArray(paramObj)) {
            paramObj = [paramObj];
        }

        paramObj.forEach(function (param) {
            attribs = param["@"];

            if (attribs) {
                paramName = attribs["name"];
                paramValue = attribs["value"];

                if (paramName && paramValue) {
                    //Add the key/value pair to the processedObj
                    processedObj[paramName] = paramValue;
                }
            }
        });
    }

    return processedObj;
}

function processFeatures(featuresArray, widgetConfig, processPredefinedFeatures) {
    var features = [],
        attribs;
    if (featuresArray) {
        featuresArray.forEach(function (feature) {
            attribs = feature["@"];
            if (attribs) {
                attribs.required = packagerUtils.toBoolean(attribs.required, true);

                // We do NOT want to auto defer networking and JavaScript if the
                // blackberry.push feature is being used
                if (attribs.id === "blackberry.push") {
                    widgetConfig.autoDeferNetworkingAndJavaScript = false;
                }

                if (_predefinedFeatures[attribs.id]) {
                    //Handle features that do NOT contain an API namespace
                    if (processPredefinedFeatures) {
                        _predefinedFeatures[attribs.id](feature, widgetConfig);
                    }
                } else {
                    features.push(attribs);
                }
            } else {
                features.push(attribs);
            }
        });
    }

    return features;
}

function createAccessListObj(uriOrOrigin, allowSubDomain) {
    return {
        uri: uriOrOrigin,
        allowSubDomain: allowSubDomain
    };
}

function processVersion(widgetConfig) {
    if (widgetConfig.version) {
        var versionArray = widgetConfig.version.split(".");

        //if 4rth number in version exists, extract for build id
        if (versionArray.length > 3) {
            widgetConfig.buildId = versionArray[3];
            widgetConfig.version = widgetConfig.version.substring(0, widgetConfig.version.lastIndexOf('.'));
        }
    }
}

function processBuildID(widgetConfig, session) {
    if (session.buildId) {
        //user specified a build id (--buildId), override any previously set build id
        widgetConfig.buildId = session.buildId;
    }
}

function processWidgetData(data, widgetConfig, session) {
    var attribs,
        featureArray,
        uriExist,
        originExist,
        header;

    if (data["@"]) {
        widgetConfig.version = data["@"].version;
        widgetConfig.id = data["@"].id;

        if (data["@"]["rim:header"]) {
            widgetConfig.customHeaders = {};
            header = data["@"]["rim:header"].split(":");
            // Just set it for now, in the future we can append them
            widgetConfig.customHeaders[header[0]] = header[1];
        }

        if (data["@"]["rim:userAgent"]) {
            widgetConfig.userAgent = data["@"]["rim:userAgent"];
        }
    }

    //Default values
    widgetConfig.hasMultiAccess = false;
    widgetConfig.accessList = [];
    widgetConfig.enableFlash = false;
    widgetConfig.autoOrientation = true;
    widgetConfig.autoDeferNetworkingAndJavaScript = true;
    widgetConfig.theme = "default";
    widgetConfig.autoHideSplashScreen = "true";

    //set locally available features to access list
    if (data.feature) {
        featureArray = packagerUtils.isArray(data.feature) ? data.feature : [data.feature];
    }

    //Handle features that do not have source code
    featureArray = processFeatures(featureArray, widgetConfig, true);

    //Push empty WIDGET_LOCAL access obj until whitelisting is cleaned up
    widgetConfig.accessList.push(createAccessListObj("WIDGET_LOCAL", true));

    //add whitelisted features to access list
    if (data.access) {
        //If there is only one access list element, it will be parsed as an object and not an array
        if (!packagerUtils.isArray(data.access)) {
            data.access = [data.access];
        }

        //check if uri and origin attributes are used
        data.access.forEach(function (accessElement, accessIndex) {
            attribs = accessElement["@"];

            if (attribs) {
                if (attribs.uri) {
                    uriExist = true;
                }
                if (attribs.origin) {
                    originExist = true;
                }
            }
        });
        if (uriExist === true && originExist === true) {
            logger.warn(localize.translate("WARNING_URI_AND_ORIGIN_FOUND_IN_CONFIG"));
        }

        data.access.forEach(function (accessElement) {
            attribs = accessElement["@"];

            if (attribs) {
                if (attribs.uri === "*" || attribs.origin === "*") {
                    if (accessElement.feature) {
                        throw localize.translate("EXCEPTION_FEATURE_DEFINED_WITH_WILDCARD_ACCESS_URI_OR_ORIGIN");
                    }
                    widgetConfig.hasMultiAccess = true;
                } else {
                    attribs.subdomains = packagerUtils.toBoolean(attribs.subdomains);
                    if (attribs.uri || attribs.origin) {
                        if (uriExist === true && originExist === true) {
                            widgetConfig.accessList.push(createAccessListObj(attribs.uri, attribs.subdomains)); //using uri attribute by default
                        } else {
                            widgetConfig.accessList.push(createAccessListObj(attribs.uri || attribs.origin, attribs.subdomains));
                        }
                    }
                }
            }
        });
    }
}

function trim(obj) {
    return (typeof obj === "string" ? obj.trim() : obj);
}

function processSplashScreenIconSrc(data, widgetConfig, key) {
    if (data[key]) {
        widgetConfig[key] = [];

        if (!(data[key] instanceof Array)) {
            data[key] = [data[key]];
        }

        data[key].forEach(function (obj) {
            if (obj["@"]) {
                widgetConfig[key].push(obj["@"].src);
            } else {
                widgetConfig[key].push(obj);
            }
        });
    }
}

function processSplashScreenData(data, widgetConfig) {
    //
    // This takes config.xml markup in the form of:
    //
    // <rim:splash src="splash-1280x768.jpg" />
    // <rim:splash src="splash-768x1280.jpg" />
    // <rim:splash src="splash-1024x600.jpg" />
    // <rim:splash src="splash-600x1024.jpg" />
    //
    // and turns it into:
    //
    // icon: ["splash-1280x768.jpg", "splash-768x1280.jpg", "splash-1024x600.jpg", "splash-600x1024.jpg"]
    //
    // Folder-based localization now done in i18n-manager
    //
    processSplashScreenIconSrc(data, widgetConfig, "rim:splash");
}

function processIconData(data, widgetConfig, session) {
    //
    // This takes config.xml markup in the form of:
    //
    // <icon src="icon-86.png" />
    // <icon src="icon-150.png" />
    //
    // and turns it into:
    //
    // icon: ["icon-86.png", "icon-150.png"]
    //
    // Folder-based localization now done in i18n-manager
    //
    var default_icon_filename = "default-icon.png",
        default_icon_src = session.conf.DEFAULT_ICON,
        default_icon_dst = session.sourceDir;

    processSplashScreenIconSrc(data, widgetConfig, "icon");

    if (!widgetConfig.icon) {
        packagerUtils.copyFile(default_icon_src, default_icon_dst);

        widgetConfig["icon"] = [];
        widgetConfig["icon"].push(default_icon_filename);
    }
}

function validateSplashScreensIcon(widgetConfig, key) {
    if (widgetConfig[key]) {
        var msg = localize.translate(key === "icon" ? "EXCEPTION_INVALID_ICON_SRC" : "EXCEPTION_INVALID_SPLASH_SRC");

        if (widgetConfig[key].length === 0) {
            // element without src attribute
            throw msg;
        } else {
            widgetConfig[key].forEach(function (src) {
                var msg2 = localize.translate(key === "icon" ? "EXCEPTION_INVALID_ICON_SRC_LOCALES" : "EXCEPTION_INVALID_SPLASH_SRC_LOCALES");

                // check that src attribute is specified and is not empty
                check(src, msg).notNull();

                // check that src attribute does not start with reserved locales folder
                src = src.replace(/\\/g, "/");
                check(src, msg2).notRegex("^" + i18nMgr.LOCALES_DIR + "\/");
            });
        }

    }
}

function processAuthorData(data, widgetConfig) {
    if (data.author) {
        var attribs = data.author["@"];

        if (!attribs && typeof data.author === "string") {
            //do not sanitize empty objects {} (must be string)
            widgetConfig.author = sanitize(data.author).trim();
        } else if (data.author["#"]) {
            widgetConfig.author = sanitize(data.author["#"]).trim();
        }

        if (attribs) {
            widgetConfig.authorURL = attribs.href;
            widgetConfig.copyright = attribs["rim:copyright"];
            widgetConfig.authorEmail = attribs.email;
        }
    }
}

function processLicenseData(data, widgetConfig) {
    if (data.license && data.license["#"]) {
        widgetConfig.license = data.license["#"];
    } else {
        widgetConfig.license = "";
    }

    if (data.license && data.license["@"]) {
        widgetConfig.licenseURL = data.license["@"].href;
    } else {
        widgetConfig.licenseURL = "";
    }
}

function processContentData(data, widgetConfig) {
    if (data.content) {
        var attribs  = data.content["@"],
            startPage;
        if (attribs) {
            widgetConfig.content = attribs.src;

            startPage = packagerUtils.parseUri(attribs.src);

            // if start page is local but does not start with local:///, will prepend it
            // replace any backslash with forward slash
            if (!packagerUtils.isAbsoluteURI(startPage) && !packagerUtils.isLocalURI(startPage)) {
                if (!startPage.relative.match(/^\//)) {
                    widgetConfig.content = "local:///" + startPage.relative.replace(/\\/g, "/");
                } else {
                    widgetConfig.content = "local://" + startPage.relative.replace(/\\/g, "/");
                }
            }

            widgetConfig.foregroundSource = attribs.src;
            widgetConfig.contentType = attribs.type;
            widgetConfig.contentCharSet = attribs.charset;
            widgetConfig.allowInvokeParams = attribs["rim:allowInvokeParams"];
            //TODO content rim:background
        }
    }
}

function processPermissionsData(data, widgetConfig) {
    if (data["rim:permissions"] && data["rim:permissions"]["rim:permit"]) {
        var permissions = data["rim:permissions"]["rim:permit"];

        if (permissions instanceof Array) {
            widgetConfig.permissions = permissions;
        } else {
            //user entered one permission and it comes in as an object
            widgetConfig.permissions = [permissions];
        }
    } else {
        widgetConfig.permissions = [];
    }

    // We do NOT want to auto defer networking and JavaScript if the
    // run_when_backgrounded permission is set
    if (widgetConfig.permissions.indexOf("run_when_backgrounded") >= 0) {
        widgetConfig.autoDeferNetworkingAndJavaScript = false;
    }
}

function processInvokeTargetsData(data, widgetConfig) {

    if (data["rim:invoke-target"]) {
        widgetConfig["invoke-target"] = data["rim:invoke-target"];

        //If invoke-target is not an array, wrap the invoke-target in an array
        utils.wrapPropertyInArray(widgetConfig, "invoke-target");

        widgetConfig["invoke-target"].forEach(function (invokeTarget) {
            if (invokeTarget.type && !packagerUtils.isEmpty(invokeTarget.type)) {
                invokeTarget.type = invokeTarget.type.toUpperCase();
            }

            if (invokeTarget.filter) {
                utils.wrapPropertyInArray(invokeTarget, "filter");

                invokeTarget.filter.forEach(function (filter) {

                    if (filter["action"]) {
                        utils.wrapPropertyInArray(filter, "action");
                    }

                    if (filter["mime-type"]) {
                        utils.wrapPropertyInArray(filter, "mime-type");
                    }

                    if (filter["property"]) {
                        utils.wrapPropertyInArray(filter, "property");
                    }
                });
            }
        });
    }
}

function validateConfig(widgetConfig) {
    check(widgetConfig.version, localize.translate("EXCEPTION_INVALID_VERSION"))
        .notNull()
        .regex("^[0-9]{1,3}([.][0-9]{1,3}){2,3}$");

    for (var prop in widgetConfig.name) {
        if (widgetConfig.name.hasOwnProperty(prop)) {
            check(widgetConfig.name[prop], localize.translate("EXCEPTION_INVALID_NAME")).notEmpty();
        }
    }

    check(widgetConfig.author, localize.translate("EXCEPTION_INVALID_AUTHOR")).notNull();
    check(widgetConfig.id, localize.translate("EXCEPTION_INVALID_ID")).notNull().notEmpty();

    validateSplashScreensIcon(widgetConfig, "rim:splash");

    validateSplashScreensIcon(widgetConfig, "icon");

    if (widgetConfig.accessList) {
        widgetConfig.accessList.forEach(function (access) {
            if (access.uri) {
                if (access.uri !== "WIDGET_LOCAL") {
                    check(access.uri, localize.translate("EXCEPTION_INVALID_ACCESS_URI_NO_PROTOCOL", access.uri))
                        .regex("^[a-zA-Z]+:\/\/");
                    check(access.uri, localize.translate("EXCEPTION_INVALID_ACCESS_URI_NO_URN", access.uri))
                        .notRegex("^[a-zA-Z]+:\/\/$");
                }
            }

            if (access.features) {
                // Assert each feature has a proper ID and is not empty
                access.features.forEach(function (feature) {
                    if (!feature) {
                        throw localize.translate("EXCEPTION_INVALID_FEATURE_ID");
                    }
                    check(feature.id, localize.translate("EXCEPTION_INVALID_FEATURE_ID")).notNull().notEmpty();
                });
            }

        });
    }

    if (widgetConfig["invoke-target"]) {

        widgetConfig["invoke-target"].forEach(function (invokeTarget) {

            check(typeof invokeTarget["@"] === "undefined",
                    localize.translate("EXCEPTION_INVOKE_TARGET_INVALID_ID"))
                .equals(false);
            check(invokeTarget["@"].id, localize.translate("EXCEPTION_INVOKE_TARGET_INVALID_ID"))
                .notNull()
                .notEmpty();
            check(invokeTarget.type, localize.translate("EXCEPTION_INVOKE_TARGET_INVALID_TYPE"))
                .notNull()
                .notEmpty();

            if (invokeTarget.filter) {

                invokeTarget.filter.forEach(function (filter) {

                    check(filter["action"] && filter["action"] instanceof Array && filter["action"].length > 0,
                            localize.translate("EXCEPTION_INVOKE_TARGET_ACTION_INVALID"))
                        .equals(true);

                    check(filter["mime-type"] && filter["mime-type"] instanceof Array && filter["mime-type"].length > 0,
                            localize.translate("EXCEPTION_INVOKE_TARGET_MIME_TYPE_INVALID"))
                        .equals(true);

                    if (filter.property) {
                        filter.property.forEach(function (property) {
                            check(property["@"] && property["@"]["var"] && typeof property["@"]["var"] === "string",
                                    localize.translate("EXCEPTION_INVOKE_TARGET_FILTER_PROPERTY_INVALID"))
                                .equals(true);
                        });
                    }
                });
            }
        });
    }
}

function processLocalizedText(tag, data, widgetConfig) {
    var tagData = data[tag],
        DEFAULT = 'default';

    function processLanguage(tagElement) {
        var attribs = tagElement['@'],
            language;

        if (attribs) {
            language = attribs['xml:lang'] || DEFAULT;
            widgetConfig[tag][language.toLowerCase()] = tagElement['#'];
        } else {
            widgetConfig[tag][DEFAULT] = tagElement;
        }
    }

    if (Array.isArray(tagData)) {
        //i.e. <element xml:lang="en">english value</element>
        //     <element xml:lang="fr">french value</element>
        tagData.forEach(processLanguage);
    } else if (tagData instanceof Object) {
        //i.e. <element xml:lang="en">english value</element>
        processLanguage(tagData);
    } else {
        //i.e <element>value</element>
        widgetConfig[tag][DEFAULT] = tagData;
    }
}

function processNameAndDescription(data, widgetConfig) {
    widgetConfig.name = {};
    widgetConfig.description = {};

    processLocalizedText('name', data, widgetConfig);
    processLocalizedText('description', data, widgetConfig);
}

function processCordovaPreferences(data, widgetConfig) {
    if (data.preference) {
        var preference = JSON.parse(JSON.stringify(processParamObj(data.preference)).toLowerCase()),
            hideFormControl = preference.hidekeyboardformaccessorybar;

        widgetConfig.packageCordovaJs = preference.packagecordovajs === "enable";
        widgetConfig.autoHideSplashScreen = preference.autohidesplashscreen !== "false";

        // <preference name="backgroundColor" value="hex" />
        if (preference.backgroundcolor) {
            widgetConfig.backgroundColor = processBgColor(preference.backgroundcolor);
        }

        // <preference name="childBrowser" value="enable or disable" />
        if (preference.childbrowser) {
            widgetConfig.enableChildWebView = (preference.childbrowser === 'disable') === false;
        }

        // <preference name="HideKeyboardFormAccessoryBar" value="enable/true or disable/false" />
        if (preference.hidekeyboardformaccessorybar) {
            widgetConfig.enableFormControl = (hideFormControl !== 'enable') && (hideFormControl !== 'true');
        }

        // <preference name="popupBlocker" value="enable or disable" />
        if (preference.popupblocker) {
            widgetConfig.enablePopupBlocker = (preference.popupblocker === 'enable') === true;
        }

        // <preference name="orientation" value="portrait, landscape, north, auto or default" />
        if (preference.orientation) {
            if (preference.orientation ===  "landscape" || preference.orientation === "portrait" || preference.orientation === "north") {
                widgetConfig.autoOrientation = false;
                widgetConfig.orientation = preference.orientation;
            } else if (preference.orientation !== "auto" && preference.orientation !== "default") {
                throw localize.translate("EXCEPTION_INVALID_ORIENTATION_MODE", preference.orientation);
            }
        }

        // <preference name="theme" value="bright, dark, inherit or default" />
        if (preference.theme && (typeof preference.theme === "string")) {
            if (preference.theme ===  "bright" || preference.theme === "dark" || preference.theme === "inherit" || preference.theme ===  "default") {
                widgetConfig.theme = preference.theme;
            }
        }

        // <preference name="webSecurity" value="enable or disable" />
        if (preference.websecurity && (typeof preference.websecurity === "string") && (preference.websecurity === "disable")) {
            widgetConfig.enableWebSecurity = false;
            logger.warn(localize.translate("WARNING_WEBSECURITY_DISABLED"));
        }

        // <preference name="diskCache" value="enable or disable" />
        if (preference.diskcache) {
            widgetConfig.enableDiskCache = (preference.diskcache === 'enable');
        }
    }
}

function processBgColor(bgColor) {
    //convert bgColor to a number
    var bgColorNum = parseInt(bgColor, 16);

    if (isNaN(bgColorNum)) {
        //bgColor is not a number, throw error
        throw localize.translate("EXCEPTION_BGCOLOR_INVALID", bgColor);
    } else {
        return bgColorNum;
    }
}

function processResult(data, session) {
    var widgetConfig = {};

    processWidgetData(data, widgetConfig, session);
    processIconData(data, widgetConfig, session);
    processAuthorData(data, widgetConfig);
    processLicenseData(data, widgetConfig);
    processContentData(data, widgetConfig);
    processPermissionsData(data, widgetConfig);
    processInvokeTargetsData(data, widgetConfig);
    processSplashScreenData(data, widgetConfig);
    processNameAndDescription(data, widgetConfig);
    processCordovaPreferences(data, widgetConfig);

    widgetConfig.configXML = "config.xml";

    //validate the widgetConfig
    validateConfig(widgetConfig);

    //special handling for version and grabbing the buildId if specified (4rth number)
    processVersion(widgetConfig);

    //if --buildId was specified, it takes precedence
    processBuildID(widgetConfig, session);

    //store any config-file element injections
    widgetConfig.configFileInjections = _config_doc.findall("config-file");

    return widgetConfig;
}

function init() {
    //Predefined features are features that do NOT contain an API namespace
    _predefinedFeatures = {
        "enable-flash" : function (feature, widgetConfig) {
            widgetConfig.enableFlash = true;
        },
        "blackberry.app.orientation": function (feature, widgetConfig) {
            if (feature) {
                var params = processParamObj(feature.param),
                    mode = params.mode;

                if (!mode) {
                    //No mode provided, throw error
                    throw localize.translate("EXCEPTION_EMPTY_ORIENTATION_MODE", mode);
                } else if (mode === "landscape" || mode === "portrait" || mode === "north") {
                    widgetConfig.autoOrientation = false;//Overwrites default value
                    widgetConfig.orientation = mode;
                } else if (mode !== "auto") {
                    //Mode invalid, throw error
                    throw localize.translate("EXCEPTION_INVALID_ORIENTATION_MODE", mode);
                }

                // Throw a warning since this feature is deprecated
                logger.warn(localize.translate("WARNING_ORIENTATION_DEPRECATED"));
            }
        }
    };
}

_self = {
    parse: function (xmlPath, session, callback) {
        if (!fs.existsSync(xmlPath)) {
            throw localize.translate("EXCEPTION_CONFIG_NOT_FOUND");
        }

        var fileData = fs.readFileSync(xmlPath),
            xml = utils.bufferToString(fileData),
            parser = new xml2js.Parser({trim: true, normalize: true, explicitRoot: false});

        //Used for config-file injections
        _config_doc = new et.ElementTree(et.XML(xml));

        init();

        //parse xml file data
        parser.parseString(xml, function (err, result) {
            if (err) {
                logger.error(localize.translate("EXCEPTION_PARSING_XML"));
                fileManager.cleanSource(session);
            } else {
                callback(processResult(result, session));
            }
        });
    }
};

module.exports = _self;
