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

function MSBuildTools (version, path) {
    this.version = version;
    this.path = path;
}

MSBuildTools.prototype.buildProject = function (projFile, buildType, buildarch, buildFlags) {
    events.emit('log', 'Building project: ' + projFile);
    events.emit('log', '\tConfiguration : ' + buildType);
    events.emit('log', '\tPlatform      : ' + buildarch);
    events.emit('log', '\tBuildflags    : ' + buildFlags);
    events.emit('log', '\tMSBuildTools  : ' + this.path);

    // Additional requirement checks
    var checkWinSDK = function (target_platform) {
        return require('./check_reqs').isWinSDKPresent(target_platform);
    };
    var checkPhoneSDK = function () {
        return require('./check_reqs').isPhoneSDKPresent();
    };

    // default build args
    var args = ['/clp:NoSummary;NoItemAndPropertyList;Verbosity=minimal', '/nologo',
        '/p:Configuration=' + buildType,
        '/p:Platform=' + buildarch];

    // add buildFlags if present
    if (buildFlags) {
        args = args.concat(buildFlags);
    }

    var that = this;
    var promise;

    // Check if SDK required to build the respective platform is present. If not present, return with corresponding error, else call msbuild.
    if (projFile.indexOf('CordovaApp.Phone.jsproj') > -1) {
        promise = checkPhoneSDK();
    } else if (projFile.indexOf('CordovaApp.Windows.jsproj') > -1) {
        promise = checkWinSDK('8.1');
    } else {
        promise = checkWinSDK('10.0');
    }

    return promise.then(function () {
        console.log('buildProject spawn:', path.join(that.path, 'msbuild'), [projFile].concat(args), { stdio: 'inherit' });
        return spawn(path.join(that.path, 'msbuild'), [projFile].concat(args), { stdio: 'inherit' });
    });
};

// check_reqs.js -> checkMSBuild()
module.exports.findAllAvailableVersions = function () {
    // console.log('findAllAvailableVersions');

    var msBuildPath = '';

    // Use MSBUILDDIR environment variable if defined to find MSBuild.
    // MSBUILDDIR = C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin
    // MSBUILDDIR = C:\Program Files (x86)\MSBuild\14.0\bin\
    if (process.env.MSBUILDDIR) {
        console.log('ENV var MSBUILDDIR is set', process.env.MSBUILDDIR);
        msBuildPath = process.env.MSBUILDDIR;
        return module.exports.getMSBuildToolsAt(msBuildPath)
            .then(function (msBuildTools) {
                return [msBuildTools];
            })
            // If MSBUILDDIR is not specified or doesn't contain a valid MSBuild
            // - fall back to default discovery mechanism.
            .catch(findAllAvailableVersionsFallBack);
    }

    // CB-11548 use VSINSTALLDIR environment if defined to find MSBuild.
    if (process.env.VSINSTALLDIR) {
        console.log('ENV var VSINSTALLDIR is set', process.env.VSINSTALLDIR);
        msBuildPath = path.join(process.env.VSINSTALLDIR, 'MSBuild/15.0/Bin');
        return module.exports.getMSBuildToolsAt(msBuildPath)
            .then(function (msBuildTools) {
                return [msBuildTools];
            })
            // If VSINSTALLDIR is not specified or doesn't contain the MSBuild path we are
            // looking for - fall back to default discovery mechanism.
            .catch(findAllAvailableVersionsFallBack);
    }

    return findAllAvailableVersionsFallBack();
};

function findAllAvailableVersionsFallBack () {
    // console.log('findAllAvailableVersionsFALLBACK');

    var versions = ['15.9', '15.5', '15.0', '14.0', '12.0', '4.0'];
    events.emit('verbose', 'Searching for available MSBuild versions...');

    return Q.all(versions.map(checkMSBuildVersion)).then(function (unprocessedResults) {
        return unprocessedResults.filter(function (item) {
            return !!item;
        });
    });
}

// returns full path to msbuild tools required to build the project and tools version
// check_reqs.js -> run()
module.exports.findAvailableVersion = function () {
    var versions = ['15.5', '15.0', '14.0', '12.0', '4.0'];

    return Q.all(versions.map(checkMSBuildVersion)).then(function (versions) {
        // console.log('findAvailableVersion', versions);
        // select first msbuild version available, and resolve promise with it
        var msbuildTools = versions[0] || versions[1] || versions[2] || versions[3] || versions[4];

        return msbuildTools ? Q.resolve(msbuildTools) : Q.reject('MSBuild tools not found');
    });
};

/**
 * Gets MSBuildTools instance for user-specified location
 *
 * @param {String}  location  FS location where to search for MSBuild
 * @returns  Promise<MSBuildTools>  The MSBuildTools instance at specified location
 */
module.exports.getMSBuildToolsAt = function (location) {
    // console.log('getMSBuildToolsAt', location);
    var msbuildExe = path.resolve(location, 'msbuild');

    // TODO: can we account on these params availability and printed version format?
    return spawn(msbuildExe, ['-version', '-nologo'])
        .then(function (output) {
            // MSBuild prints its' version as 14.0.25123.0, so we pick only first 2 segments
            var version = output.match(/^(\d+\.\d+)/)[1];
            // console.log('return `new MSBuildTools`', version, location);
            return new MSBuildTools(version, location);
        });
};

function checkMSBuildVersion (version) {
    // console.log('checkMSBuildVersion', version);

    // first, check if we have a VS 2017+ with such a version
    var willows = module.exports.getWillowInstallations();
    // console.log('willows', willows);
    var correspondingWillows = willows.filter(function (inst) {
        // console.log('willows.filter', inst.version, version, inst.version === version);
        return inst.version === version;
    });
    // console.log('correspondingWillows', correspondingWillows);
    var correspondingWillow = correspondingWillows[0]; // TODO Do not only handle one!
    if (correspondingWillow) {
        // super hacky: VS2017/Willow is 15.x but MSBuild is always 15.0 in path - so set that here
        version = '15.0';
        var toolsPath = path.join(correspondingWillow.path, 'MSBuild', version, 'Bin');
        // console.log('matching VS:', version, toolsPath);
        // console.log('from list of VS installations: ', correspondingWillows);
        if (shell.test('-e', toolsPath)) {
            var msbuild = module.exports.getMSBuildToolsAt(toolsPath);
            // console.log('selected VS exists:', toolsPath);
            // TODO check for JavaScript folder
            return msbuild;
        }
    }

    // older vs versions that were registered in registry
    return spawn('reg', ['query', 'HKLM\\SOFTWARE\\Microsoft\\MSBuild\\ToolsVersions\\' + version, '/v', 'MSBuildToolsPath'])
        .then(function (output) {
            // console.log('spawn', output);
            // fetch msbuild path from 'reg' output
            var toolsPath = /MSBuildToolsPath\s+REG_SZ\s+(.*)/i.exec(output);
            if (toolsPath) {
                toolsPath = toolsPath[1];
                // CB-9565: Windows 10 invokes .NET Native compiler, which only runs on x86 arch,
                // so if we're running an x64 Node, make sure to use x86 tools.
                if ((version === '15.0' || version === '14.0') && toolsPath.indexOf('amd64') > -1) {
                    toolsPath = path.resolve(toolsPath, '..');
                }
                events.emit('verbose', 'Found MSBuild v' + version + ' at ' + toolsPath);
                return new MSBuildTools(version, toolsPath);
            }
        }).catch(function (err) { /* eslint handle-callback-err : 0 */
            // console.log('no registry result for version ' + version);
            // if 'reg' exits with error, assume that registry key not found
        });
}

// build.js -> run()
module.exports.getLatestMatchingMSBuild = function (selectedBuildTargets) {
    events.emit('verbose', 'getLatestMatchingMSBuild');
    // console.log('getLatestMatchingMSBuild', selectedBuildTargets);
    // TODO
    // 1. findAllAvailableVersions
    // 2. filter down to versions that can build all selectedBuildTargets
    // 3. filter for latest one of those
    return this.getLatestMSBuild()
        .then(function (msbuild) {
            // filter targets to make sure they are supported on this development machine
            var myBuildTargets = filterSupportedTargets(selectedBuildTargets, msbuild);
            return [msbuild, myBuildTargets];
        });
};

// gets the latest MSBuild version from a list of versions
module.exports.getLatestMSBuild = function () {
    events.emit('verbose', 'getLatestMSBuild');

    return this.findAllAvailableVersions()
        .then(function (allMsBuildVersions) {

            var availableVersions = allMsBuildVersions
                .filter(function (buildTools) {
                    // Sanitize input - filter out tools w/ invalid versions
                    return Version.tryParse(buildTools.version);
                }).sort(function (a, b) {
                    // Sort tools list - use parsed Version objects for that
                    // to respect both major and minor versions segments
                    var parsedA = Version.fromString(a.version);
                    var parsedB = Version.fromString(b.version);

                    if (parsedA.gt(parsedB)) return -1;
                    if (parsedA.eq(parsedB)) return 0;
                    return 1;
                });

            // console.log('availableVersions', availableVersions);

            if (availableVersions.length > 0) {
                // After sorting the first item will be the highest version available
                var msbuild = availableVersions[0];
                events.emit('verbose', 'Using MSBuild v' + msbuild.version + ' from ' + msbuild.path);
                return msbuild;
            }
        });
};

var projFiles = {
    phone: 'CordovaApp.Phone.jsproj',
    win: 'CordovaApp.Windows.jsproj',
    win10: 'CordovaApp.Windows10.jsproj'
};

// TODO: Fix this so that it outlines supported versions based on version criteria:
// - v14: Windows 8.1, Windows 10
// - v12: Windows 8.1
function msBuild12TargetsFilter (target) {
    return target === projFiles.win || target === projFiles.phone;
}

function msBuild14TargetsFilter (target) {
    return target === projFiles.win || target === projFiles.phone || target === projFiles.win10;
}

function msBuild15TargetsFilter (target) {
    return target === projFiles.win || target === projFiles.phone || target === projFiles.win10;
}

function msBuild155TargetsFilter (target) {
    return target === projFiles.win10;
}

function filterSupportedTargets (targets, msbuild) {
    // console.log('MSBuildTools->filterSupportedTargets', targets, msbuild);
    if (!targets || targets.length === 0) {
        events.emit('warn', 'No build targets specified');
        return [];
    }

    var targetFilters = {
        '12.0': msBuild12TargetsFilter,
        '14.0': msBuild14TargetsFilter,
        '15.x': msBuild15TargetsFilter,
        '15.5': msBuild155TargetsFilter,
        get: function (version) {
            // Apart from exact match also try to get filter for version range
            // so we can find for example targets for version '15.1'
            return this[version] || this[version.replace(/\.\d+$/, '.x')];
        }
    };

    var filter = targetFilters.get(msbuild.version);
    if (!filter) {
        events.emit('warn', 'MSBuild v' + msbuild.version + ' is not supported, aborting.');
        return [];
    }

    var supportedTargets = targets.filter(filter);
    // unsupported targets have been detected
    if (supportedTargets.length !== targets.length) {
        events.emit('warn', 'Not all desired build targets are compatible with the current build environment. ' +
            'Please install Visual Studio 2015 for Windows 8.1 and Windows 10, ' +
            'or Visual Studio 2013 Update 2 for Windows 8.1.');
    }
    return supportedTargets;
}

/**
 * Lists all VS 2017+ instances dirs in ProgramData
 *
 * @return {String[]} List of paths to all VS2017+ instances
 */
function getWillowProgDataPaths () {
    if (!process.env.systemdrive) {
        // running on linux/osx?
        return [];
    }
    var instancesRoot = path.join(process.env.systemdrive, 'ProgramData/Microsoft/VisualStudio/Packages/_Instances');
    if (!shell.test('-d', instancesRoot)) {
        // can't seem to find VS instances dir, return empty result
        return [];
    }

    return fs.readdirSync(instancesRoot).map(function (file) {
        var instanceDir = path.join(instancesRoot, file);
        if (shell.test('-d', instanceDir)) {
            return instanceDir;
        }
    }).filter(function (progDataPath) {
        // make sure state.json exists
        return shell.test('-e', path.join(progDataPath, 'state.json'));
    });
}

/**
 * Lists all installed VS 2017+ versions
 *
 * @return {Object[]} List of all VS 2017+ versions
 */
module.exports.getWillowInstallations = function () {
    var progDataPaths = getWillowProgDataPaths();
    var installations = [];
    progDataPaths.forEach(function (progDataPath) {
        try {
            var stateJsonPath = path.join(progDataPath, 'state.json');
            var fileContents = fs.readFileSync(stateJsonPath, 'utf-8');
            var state = JSON.parse(fileContents);
            // get only major and minor version
            var version = state.product.version.match(/^(\d+\.\d+)/)[1];
            installations.push({ version: version, path: state.installationPath });
        } catch (err) {
            // something's wrong, skip this one
        }
    });
    return installations;
};

// returns an array of available UAP Versions
// prepare.js
module.exports.getAvailableUAPVersions = function () {
    var programFilesFolder = process.env['ProgramFiles(x86)'] || process.env['ProgramFiles'];
    // No Program Files folder found, so we won't be able to find UAP SDK
    if (!programFilesFolder) return [];

    var uapFolderPath = path.join(programFilesFolder, 'Windows Kits', '10', 'Platforms', 'UAP');
    if (!shell.test('-e', uapFolderPath)) {
        return []; // No UAP SDK exists on this machine
    }

    var result = [];
    shell.ls(uapFolderPath).filter(function (uapDir) {
        return shell.test('-d', path.join(uapFolderPath, uapDir));
    }).map(function (folder) {
        return Version.tryParse(folder);
    }).forEach(function (version, index) {
        if (version) {
            result.push(version);
        }
    });

    return result;
};
