/**
 * tizen_utils.js
 * Copyright (c) 2000 - 2017 Samsung Electronics Co., Ltd. All rights reserved.
 *
 * Contact:
 * Sungmin Kim <sm.art.kim@samsung.com>
 * Jonghwan Park <iwin100.park@samsung.com>
 * Kitae Kim <kt920.kim@samsung.com>
 *
 * 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.
 *
 * Contributors:
 * - S-Core Co., Ltd
**/

var _ = require('underscore');
var path = require('path');
var os = require('os');

var dibs = require('../../core/dibs.js');
var Process = require('../dibs.core/process.js');

/**
 * @module models/tizen-common/tizenUtils
 */

/**
 * @typedef host
 * @property {string} os
 * @property {string} category
 * @memberOf module:models/tizen-common/tizenUtils
 */

/**
 * @function getTargetOS
 * @param {string} platform
 * @param {string} arch
 * @returns {module:models/tizen-common/tizenUtils.host}
 * @memberOf module:models/tizen-common/tizenUtils
 */
function getTargetOS(platform, arch) {
    var result = {};
    var arch_num = arch.replace(/[^0-9]/g, '');
    if (arch_num.length !== 2) {
        return result;
    }

    switch (platform.toLowerCase()) {
    case 'linux': result = {
            os: 'ubuntu-' + arch_num,
            category: 'linux'
        };
        break;
    case 'win32': result = {
            os: 'windows-' + arch_num,
            category: 'windows'
        };
        break;
    case 'darwin': result = {
            os: 'macos-' + arch_num,
            category: 'macos'
        };
        break;
    default : result = {};
    }
    return result;
}
module.exports.getTargetOS = getTargetOS;

/**
 * @function getOSCategory
 * @param {string} os
 * @returns {string}
 * @memberOf module:models/tizen-common/tizenUtils
 */
function getOSCategory(os) {
    if (os) {
        if (os.indexOf('ubuntu') >= 0 || os.indexOf('Ubuntu') >= 0) {
            return 'linux';
        }
        if (os.indexOf('windows') >= 0 || os.indexOf('Windows') >= 0) {
            return 'windows';
        }
        if (os.indexOf('macos') >= 0 || os.indexOf('MacOS') >= 0 || os.indexOf('OSX') >= 0) {
            return 'macos';
        }
    } else {
        return '';
    }
}
module.exports.getOSCategory = getOSCategory;

/**
 * @function getHost
 * @param {Array.<string>} environments
 * @returns {module:models/tizen-common/tizenUtils.host}
 * @memberOf module:models/tizen-common/tizenUtils
 */
module.exports.getHost = function (environments) {
    var envIds = getEnvironmentIds('Tizen-Source');
    var environment = _.find(environments, function (env) {
        return (_.find(envIds, function (id) {
            return (env.id === id);
        }));
    });
    if (environment) {
        return {
            os: environment.name,
            category: getOSCategory(environment.name)
        };
    } else {
        return {};
    }
};


function getEnvironmentIds(prjType) {
    if (!dibs.plugin) {
        dibs.initialize();
    }

    var exts = dibs.plugin.getExtensions('dibs.base.projectType');
    var prjExt = _.find(exts, function (ext) {
        return ext.projectType === prjType;
    });
    if (prjExt) {
        return prjExt.environments;
    } else {
        return [];
    }
}
module.exports.getEnvironmentIds = getEnvironmentIds;

module.exports.getEnvironmentNames = function (prjType) {
    if (!dibs.plugin) {
        dibs.initialize();
    }

    var exts = dibs.plugin.getExtensions('dibs.base.environment');
    var prjIdList = getEnvironmentIds(prjType);
    return _.map(_.filter(exts, function (ext) {
        return _.indexOf(prjIdList, ext.id) > -1;
    }), function (ext) {
        return ext.name;
    });
};


function getOsList(prjType) {
    if (!dibs.plugin) {
        dibs.initialize();
    }

    // get project type extension
    var prjExts = dibs.plugin.getExtensions('dibs.base.projectType').filter(function (ext) {
        return ext.attributes.projectType === prjType;
    });
    if (prjExts.length === 0) {
        return [];
    }
    var prjExt = prjExts[0];

    // get environment extensions
    var envExts = dibs.plugin.getExtensions('dibs.base.environment').filter(function (ext) {
        return prjExt.attributes.environments.indexOf(ext.attributes.id) > -1;
    });

    // return list of os names
    return envExts.map(function (ext) {
        return ext.attributes.name;
    });
}
module.exports.getOsList = getOsList;


function checkCancelBeforeCallback(job) {
    return function () {
        if (job && job.canceled === true) {
            var error = new Error('job #' + job.id + ' is canceled !!');
            arguments[arguments.length - 1].apply(null, [error]);
            return;
        }
        var args = Array.prototype.slice.call(arguments, 0);
        args.pop();
        args.unshift(null);
        arguments[arguments.length - 1].apply(null, args);
    };
}
module.exports.checkCancelBeforeCallback = checkCancelBeforeCallback;


function getInfoFromPackageFileName(fileName) {
    var regExp = /(.*)_(.*)_(.*)\.zip/;

    var result = regExp.exec(fileName);
    if (!result) {
        return null;
    }
    if (result[1] === '' || result[2] === '' || result[3] === '') {
        return null;
    }

    return {
        name: result[1],
        version: result[2],
        os: result[3]
    };
}
module.exports.getInfoFromPackageFileName = getInfoFromPackageFileName;


function getPackageFileNameFromInfo(name, version, os) {
    return name + '_' + version + '_' + os + '.zip';
}
module.exports.getPackageFileNameFromInfo = getPackageFileNameFromInfo;


function getEnvironments(prjType) {
    var exts = dibs.plugin.getExtensions('dibs.base.environment');
    var prjIdList = getEnvironmentIds(prjType);
    return _.filter(exts, function (ext) {
        return _.indexOf(prjIdList, ext.id) > -1;
    });
}
module.exports.getEnvironments = getEnvironments;

module.exports.EnvironmentName2Id = function (prjType, envName) {
    var prjEnvList = getEnvironments(prjType);
    var id = _.find(prjEnvList, function (prjEnv) {
        return prjEnv.name === envName;
    });
    if (id) return id.id;
    else return null;
};


module.exports.extractPackageFile = function (pkgFile, targetDir, options) {
    var ext = path.extname(pkgFile);
    var cmd = null;
    var args = [];
    switch (ext) {
    case '.zip':
        if (os.platform() === 'win32') {
            cmd = '7z';
            if (options.targetFile) {
                args = ['x', '-o' + targetDir, pkgFile, options.targetFile];
            } else {
                args = ['x', '-o' + targetDir, pkgFile];
            }
        } else {
            cmd = 'unzip';
            if (options.targetFile) {
                args = ['-o', pkgFile, options.targetFile, '-d', targetDir];
            } else {
                args = ['-o', pkgFile, '-d', targetDir];
            }
        }
        break;
    case '.tar':
        cmd = 'tar';
        args = ['-xf', pkgFile, '-C', targetDir];
        break;
    default:
        return null;
    }


    return Process.create(cmd, args, {
        cwd: process.cwd(),
        env: process.env
    }, {
        onStdout: options.onStdout,
        onStderr: options.onStderr,
        onExit: options.onExit
    });
};

module.exports.knownFileExtensions = function () {
    return ['.zip', '.tar', '.7z', '.gzip', '.gz'];
};

