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

var fs = require("fs"),
    path = require("path"),
    utils = require("./utils"),
    targetUtils = require("./target-utils.js"),
    localize = require("./localize"),
    pkgrUtils = require("./packager-utils"),
    debugTokenHelper = require("./debugtoken-helper"),
    xml2js = require('xml2js'),
    logger = require("./logger"),
    async = require("async"),
    session = require("./session"),
    properties = utils.getProperties(),
    workingdir = path.normalize(__dirname + "/.."),
    _self;

//Options looking for are: (Device | Emulator, query, devicepass). Calls back with:  (error || options object, target object)
function getTargetName(options, done) {
    var ipFinder = options.emulator ? targetUtils.findConnectedSimulator : targetUtils.findConnectedDevice,
        targetType = options.emulator ? "emulator" : "device";

    if (options.target) {
        done(null, options, options.target);
    } else {
        
        if (options.device && options.emulator) {
            localize.translate("WARN_RUN_DEVICE_OVERRIDES_EMULATOR");
        }

        async.series(
        {
            ip: function (done) {
                ipFinder(function (ip) {
                    done(ip ? null : "No connected BlackBerry 10 " + targetType + " found", ip);
                });
            },
            devicePass: function (done) {
                if (!options.devicepass && options.devicepass !== "") {
                    if (options.query) {
                        utils.prompt({description: getPasswordPrompt(targetType), hidden: true}, done);
                    } else {
                        done("");
                    }
                } else {
                    done(null, options.devicepass);
                }
            }
        },
        function (err, results) {
            if (err) {
                done(err);
            } else {
                options.devicepass = results.devicePass;
                _self.checkDeviceInfo(options, results.ip, targetType, results.devicePass, done);
            }
        });
    }
}

//Options looking for are: (query, devicepass). Calls back with:  (error || target object)
function validateTarget(options, targetName, allDone) {
    var deployTarget,
        err,
        runTasks = [];

    if (!targetName) {
        err = "No target exists, to add that target please run: target add <name> <ip> [-t | --type <device | simulator>] [-p <password>] [--pin <devicepin>]";
    } else if (!properties.targets[targetName]) {
        err = "The target \"" + targetName + "\" does not exist, to add that target please run: target add " + targetName + " <ip> [-t | --type <device | simulator>] [-p <password>] [--pin <devicepin>]";
    } else {
        deployTarget = utils.clone(properties.targets[targetName]);
        deployTarget.name = targetName;

        if (!deployTarget.ip) {
            if (options.query) {
                runTasks.push(function (done) {
                    utils.prompt({description: "Please enter the IP address for target " + deployTarget.name + ": "}, function (e, ip) {
                        deployTarget.ip = ip;
                        done(e);
                    });
                });
            } else {
                err = "IP is not defined in target \"" + deployTarget.name + "\"";
            }
        }

        if (err === undefined && !deployTarget.password && deployTarget.password !== "") {
            if (options.devicepass || options.devicepass === "") {
                deployTarget.password = options.devicepass;
            } else {
                if (options.query) {
                    runTasks.push(function (done) {
                        utils.prompt({description: getPasswordPrompt(deployTarget.type), hidden: true}, function (e, devicePass) {
                            deployTarget.password = devicePass;
                            done(e);
                        });
                    });
                } else if (!options.emulator) {
                    err = "No device password provided. You can omit --no-query, use --devicepass, or enter a value for 'password' to the target " + deployTarget.name + " defined at " + utils.getPropertiesFilePath();
                }
            }
        }

        if (!deployTarget.pin) {
            runTasks.push(function (done) {
                targetUtils.getDeviceInfo(deployTarget.ip, deployTarget.password, function (err, result) {
                    deployTarget.pin = result.pin;
                    done(err);
                });
            });
        }
    }

    async.series(runTasks, function (e) {
        var finalErr = err || e;
        if (!finalErr && deployTarget) {
            logger.info("Target " + deployTarget.name + " selected");
        }
        allDone(err || e, options, deployTarget);
    });
}
//Options looking for are: (keystorepass, query). Calls back with:  (error || target object)
function handleDebugToken(options, deployTarget, allDone) {
    options.keystorepass = session.getKeyStorePass(options);

    // deploy debug token for device debug builds only
    if (deployTarget.pin && !options.emulator && options.build && !options.release) {
        async.waterfall(
            [
                debugTokenHelper.checkDebugToken.bind(this, deployTarget.pin),
                function (done) {
                    //If no keystorepass is provided debugTokenHelper will throw an error.
                    if (!options.keystorepass && options.query) {
                        utils.prompt({description: "Please enter your keystore password: ", hidden: true}, function (err, result) {
                            options.keystorepass = result;
                            done(null, result);
                        });
                    } else {
                        done(null, options.keystorepass);
                    }
                },
                debugTokenHelper.createToken.bind(this, properties, "all")
            ],
            function (err, results) {
                // If the error is true, then the debug token is valid and creation was skipped.
                if (err === true) {
                    logger.info(localize.translate("PROGRESS_DEBUG_TOKEN_IS_VALID"));
                    //Clear the error so it is still deployed
                    err = null;
                }

                if (!err) {
                    debugTokenHelper.deployToken(deployTarget.name, deployTarget.ip, deployTarget.password, function (code) {
                        allDone(code, deployTarget);
                    });
                } else {
                    allDone(null, deployTarget);
                }
            }
        );
    } else {
        allDone(null, deployTarget);
    }
}

function generateDeployOptions(options, deployTarget) {
    var deployOptions = [],
        barPath = pkgrUtils.escapeStringForShell(
            path.normalize(__dirname + "/../../build/" +
                (deployTarget.type === "device" ? "device" : "simulator") +
                "/" + utils.genBarName() + ".bar"));

    deployOptions.push("-device");
    deployOptions.push(deployTarget.ip);

    if (deployTarget.password) {
        deployOptions.push("-password");
        deployOptions.push(deployTarget.password);
    }

    deployOptions.push("-package");
    deployOptions.push(barPath);
    deployOptions.push("-uninstallApp");
    deployOptions.push("-installApp");

    if (options.launch) {
        deployOptions.push("-launchApp");
    }

    return deployOptions;
}

function execNativeDeploy(deployOptions, callback) {
    var script = path.normalize(path.join(process.env.CORDOVA_BBTOOLS, "blackberry-deploy"));

    utils.exec(script, deployOptions, {
        "cwd": workingdir,
        "env": process.env
    }, callback);
}

function getPasswordPrompt(targetType) {
    var prompt = "Please enter your " + targetType + " password";
    if (targetType === "emulator") {
        prompt += " (For no password press ENTER)";
    }
    prompt += ": ";
    return prompt;
}

_self = {
    //options looking for are: (query, devicepass, password, target, (device || emulator)) Function returns (error || deployTarget)
    getValidatedTarget : function (options, callback) {
        async.waterfall(
            [
                getTargetName.bind(this, options),
                validateTarget,
                handleDebugToken
            ], callback
        );
    },

    //Function returns (error || null)
    install : function (options, deployTarget, allDone) {
        var script = path.join(process.env.CORDOVA_BBTOOLS, "blackberry-deploy"),
            args = [
                "-device",
                deployTarget.ip
            ],
            projectRootDir = path.normalize(path.join(__dirname, "..")),
            installedAppsOutput,
            runTasks = [];

        if (deployTarget.password) {
            args.push("-password", deployTarget.password);
        }
        runTasks = [
            function uninstallInstallLaunchApp(result, done) {
                var deployOptions = generateDeployOptions(options, deployTarget);
                execNativeDeploy(deployOptions, done);
            }
        ];

        async.waterfall(runTasks,
            function (err, results) {
                allDone(null, deployTarget);
            }
        );
    },

    //Function returns (error || deployTarget)
    checkBuild : function (deployTarget, allDone) {
        var barPath = path.normalize(__dirname + "/../../build/" +
                (deployTarget.type === "device" ? "device" : "simulator") +
                "/" + utils.genBarName() + ".bar");
        if (fs.existsSync(barPath)) {
            allDone(null, deployTarget);
        } else {
            allDone("No build file exists, please run: build [--debug | --release] [--keystorepass <password>] [--buildId <number>] [--params <json>] [--loglevel <level>] [--web-inspector] [--no-signing]");
        }
    },

    //No options needed within function Function returns (error || options, targetName)
    checkDeviceInfo : function (options, ip, deviceType, devicePass, done) {
        var props = utils.getProperties(),
            targetName;

        targetUtils.getDeviceInfo(ip, devicePass, function (err, device) {
            if (!err) {
                targetName = device.name.replace(/ /g, "-") + "-" + device.pin;
                props.targets[targetName] = {
                    ip: ip,
                    pin: device.pin,
                    type: deviceType
                };
                utils.writeToPropertiesFile(props);
            }
            done(err, options, targetName);
        });
    }
};

module.exports = _self;
