/*
       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 Q = require('q');
var fs = require('fs');
var path = require('path');
var spawn = require('cordova-common').superspawn.spawn;
var events = require('cordova-common').events;

var E_INVALIDARG = 2147942487;

function DeploymentTool () {
}

/**
 * Determines whether the requested version of the deployment tool is available.
 * @returns True if the deployment tool can function; false if not.
 */
DeploymentTool.prototype.isAvailable = function () {
    return fs.existsSync(this.path);
};

/**
 * Enumerates devices attached to the development machine.
 * @returns A Promise for an array of objects, which should be passed into other functions to represent the device.
 * @remarks The returned objects contain 'index', 'name', and 'type' properties indicating basic information about them,
 *    which is limited to the information provided by the system.  Other properties may also be included, but they are
 *    specific to the deployment tool which created them and are likely used internally.
 */
DeploymentTool.prototype.enumerateDevices = function () {
    return Q.reject('May not use DeploymentTool directly, instead get an instance from DeploymentTool.getDeploymentTool()');
};

/**
 * Installs an app package to the target device.
 * @returns A Promise which will be fulfilled on success or rejected on failure.
 * @param pathToAppxPackage The path to the .appx package to install.
 * @param targetDevice An object returned from a successful call to enumerateDevices.
 * @shouldLaunch Indicates whether to launch the app after installing it.
 * @shouldUpdate Indicates whether to explicitly update the app, or install clean.
 * @pin Optionally provided if the device requires pairing for deployment.
 */
DeploymentTool.prototype.installAppPackage = function (pathToAppxPackage, targetDevice, shouldLaunch, shouldUpdate, pin) {
    return Q.reject('May not use DeploymentTool directly, instead get an instance from DeploymentTool.getDeploymentTool()');
};

/**
 * Uninstalls an app package from the target device.
 * @returns A Promise which will be fulfilled on success or rejected on failure.
 * @param packageInfo The app package name or Phone GUID representing the app.
 * @param targetDevice An object returned from a successful call to enumerateDevices.
 */
DeploymentTool.prototype.uninstallAppPackage = function (packageInfo, targetDevice) {
    return Q.reject('Unable to uninstall any app packages because that feature is not supported.');
};

/**
 * Gets a list of installed apps on the target device.  This function is not supported for
 * Windows Phone 8.1.
 * @param targetDevice {Object} An object returned from a successful call to enumerateDevices.
 * @returns A Promise for an array of app names.
 */
DeploymentTool.prototype.getInstalledApps = function (targetDevice) {
    return Q.reject('Unable to get installed apps because that feature is not supported.');
};

/**
 * Launches an app on the target device.  This function is not supported for Windows 10.
 * @param packageInfo {String} The app package name or Phone GUID representing the app.
 * @param targetDevice {Object} An object returned from a successful call to enumerateDevices.
 * @returns A Promise for when the app is launched.
 */
DeploymentTool.prototype.launchApp = function (packageInfo, targetDevice) {
    return Q.reject('Unable to launch an app because that feature is not supported.');
};

/**
 * Gets a DeploymentTool to deploy to devices or emulators.
 * @param targetOsVersion {String} The version of the
 */
DeploymentTool.getDeploymentTool = function (targetOsVersion) {
    if (targetOsVersion === '8.1') {
        return new AppDeployCmdTool(targetOsVersion);
    } else {
        return new WinAppDeployCmdTool(targetOsVersion);
    }
};

// DeviceInfo is an opaque object passed to install/uninstall.
// Implementations of DeploymentTool can populate it with any additional
//  information required for accessing them.
function DeviceInfo (deviceIndex, deviceName, deviceType) {
    this.index = deviceIndex;
    this.name = deviceName;
    this.type = deviceType;
}

DeviceInfo.prototype.toString = function () {
    return this.index + '. ' + this.name + ' (' + this.type + ')';
};

function AppDeployCmdTool (targetOsVersion) {
    if (!(this instanceof AppDeployCmdTool)) { throw new ReferenceError('Only create an AppDeployCmdTool as an instance object.'); }

    DeploymentTool.call(this);
    this.targetOsVersion = targetOsVersion;

    var programFilesPath = process.env['ProgramFiles(x86)'] || process.env['ProgramFiles'];
    this.path = path.join(programFilesPath, 'Microsoft SDKs', 'Windows Phone', 'v' + this.targetOsVersion, 'Tools', 'AppDeploy', 'AppDeployCmd.exe');
}

AppDeployCmdTool.prototype = Object.create(DeploymentTool.prototype);
AppDeployCmdTool.prototype.constructor = AppDeployCmdTool;

AppDeployCmdTool.prototype.enumerateDevices = function () {
    var that = this;
    //  9              Emulator 8.1 720P 4.7 inch\r\n
    //    maps to
    // [(line), 9, 'Emulator 8.1 720P 4.7 inch']
    // Expansion is: space, index, spaces, name
    var LINE_TEST = /^\s(\d+?)\s+(.+?)$/m;
    return spawn(that.path, ['/EnumerateDevices']).then(function (result) {
        var lines = result.split('\n');
        var matchedLines = lines.filter(function (line) {
            return LINE_TEST.test(line);
        });

        var devices = matchedLines.map(function (line, arrayIndex) {
            var match = line.match(LINE_TEST);
            var index = parseInt(match[1], 10);
            var name = match[2];

            var shorthand = '';
            var type = 'emulator';

            if (name === 'Device') {
                shorthand = 'de';
                type = 'device';
            } else if (arrayIndex === 1) {
                shorthand = 'xd';
            } else {
                shorthand = index;
            }
            var deviceInfo = new DeviceInfo(index, name, type);
            deviceInfo.__sourceLine = line;
            deviceInfo.__shorthand = shorthand;
            return deviceInfo;
        });

        return devices;
    });
};

// Note: To account for CB-9482, we pass an extra parameter when retrying the call.  Be forwarned to check for that
// if additional parameters are added in the future.
AppDeployCmdTool.prototype.installAppPackage = function (pathToAppxPackage, targetDevice, shouldLaunch, shouldUpdate, pin) {
    var command = shouldUpdate ? '/update' : '/install';
    if (shouldLaunch) {
        command += 'launch';
    }

    var that = this;
    var result = spawn(this.path, [command, pathToAppxPackage, '/targetdevice:' + targetDevice.__shorthand]);
    if (targetDevice.type === 'emulator') {
        result = result.then(null, function (e) {
            // CB-9482: AppDeployCmd also reports E_INVALIDARG during this process.  If so, try to repeat.
            if (e.code === E_INVALIDARG) {
                return spawn(that.path, [command, pathToAppxPackage, '/targetdevice:' + targetDevice.__shorthand]);
            }

            throw e;
        });
    }

    return result;
};

AppDeployCmdTool.prototype.uninstallAppPackage = function (packageInfo, targetDevice) {
    // CB-9482: AppDeployCmd reports failure when targeting an emulator, but actually succeeds
    //  Further calls in the promise chain then are not executed (such as installAppPackage) because
    //  of the failure reported here.  By ensuring that this function always reports a success
    //  state, it allows install to proceed.  (Install will fail if there is a legitimate
    //  uninstall failure such as due to no device).
    var assureSuccess = function () {};
    return spawn(this.path, ['/uninstall', packageInfo, '/targetdevice:' + targetDevice.__shorthand]).then(assureSuccess, assureSuccess);
};

AppDeployCmdTool.prototype.launchApp = function (packageInfo, targetDevice) {
    return spawn(this.path, ['/launch', packageInfo, '/targetdevice:' + targetDevice.__shorthand]);
};

function WinAppDeployCmdTool (targetOsVersion) {
    if (!(this instanceof WinAppDeployCmdTool)) { throw new ReferenceError('Only create a WinAppDeployCmdTool as an instance object.'); }

    DeploymentTool.call(this);
    this.targetOsVersion = targetOsVersion;
    var programFilesPath = process.env['ProgramFiles(x86)'] || process.env['ProgramFiles'];
    this.path = path.join(programFilesPath, 'Windows Kits', '10', 'bin', 'x86', 'WinAppDeployCmd.exe');
}

WinAppDeployCmdTool.prototype = Object.create(DeploymentTool.prototype);
WinAppDeployCmdTool.prototype.constructor = WinAppDeployCmdTool;

WinAppDeployCmdTool.prototype.enumerateDevices = function () {
    var that = this;
    // 127.0.0.1   00000015-b21e-0da9-0000-000000000000    Lumia 1520 (RM-940)\r
    //  maps to
    // [(line), '127.0.0.1', '00000015-b21e-0da9-0000-000000000000', 'Lumia 1520 (RM-940)']
    // The expansion is: IP address, spaces, GUID, spaces, text name

    var LINE_TEST = /^([\d\.]+?)\s+([\da-fA-F\-]+?)\s+(.+)$/m; /* eslint no-useless-escape : 0 */

    return spawn(that.path, ['devices']).then(function (result) {
        var lines = result.split('\n');
        var matchedLines = lines.filter(function (line) {
            return LINE_TEST.test(line);
        });

        var devices = matchedLines.map(function (line, arrayIndex) {
            var match = line.match(LINE_TEST);
            var ip = match[1];
            var guid = match[2];
            var name = match[3];
            var type = 'device';

            var deviceInfo = new DeviceInfo(arrayIndex, name, type);
            deviceInfo.__ip = ip;
            deviceInfo.__guid = guid;

            return deviceInfo;
        });

        return devices;
    });
};

WinAppDeployCmdTool.prototype.installAppPackage = function (pathToAppxPackage, targetDevice, shouldLaunch, shouldUpdate, pin) {
    if (shouldLaunch) {
        events.emit('warn', 'Cannot launch app with current version of Windows 10 SDK tools. ' +
            'You will have to launch the app after installation is completed.');
    }

    var args = [shouldUpdate ? 'update' : 'install', '-file', pathToAppxPackage, '-ip', targetDevice.__ip];
    if (pin) {
        args.push('-pin');
        args.push(pin);
    }

    return spawn(this.path, args).then(function () {
        events.emit('log', 'Deployment completed successfully.');
    });
};

WinAppDeployCmdTool.prototype.uninstallAppPackage = function (packageInfo, targetDevice) {
    return spawn(this.path, ['uninstall', '-package', packageInfo, '-ip', targetDevice.__ip]);
};

// usage: require('deployment').getDeploymentTool('8.1');
module.exports = DeploymentTool;
