/**
 * archive-project.js
 * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
 *
 * Contact:
 * DongHee Yang <donghee.yang@samsung.com>
 * Sungmin Kim <sm.art.kim@samsung.com>
 * Jiil Hyoun <jiil.hyoun@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 path = require('path');
var async = require('async');

var DError = require('../../core/exception');
var dibs = require('../../core/dibs');
var Job = require('../dibs.model.common/job.js');
var TizenCommon = require('../org.tizen.common/tizen_common.js');

/**
 * Tizen archive project plugin
 * @module models/tizen-archive-project/project
 */

/**
 * Tizen archive job
 * @constructor
 * @augments module:models/job
 * @param {module:models/job~Job} baseJob - base job object
 */

function TizenArchiveJob(baseJob) {
    Job.copy(this, baseJob);

    this.compatJob = null;
    this.callback = null;
    if (!this.options.packages) {
        this.options.packages = [];
    }

    // NOTE. Initializing/Executing on windows is very slow
    this.initEnvironments = dibs.projectTypes['Tizen-Archive'].environments
        .filter(function (e) {
            return (e.indexOf('windows') === -1);
        });
    this.execEnvironments = dibs.projectTypes['Tizen-Archive'].environments
        .filter(function (e) {
            return (e.indexOf('windows') === -1);
        });
}

/**
 * Create tizen git job instance
 * @function createJob
 * @param {string} prjName - project name
 * @param {string} prjType - project type
 * @param {string} distName - distribution name
 * @param {module:models/job.options} options - job options
 * @param {module:lib/utils.callback_error} callback - callback(error)
 * @memberOf module:models/tizen-project/project
 */

function createJob(userEmail, distName, prjName, prjType, environmentName, parentId, distType, options, callback) {
    Job.create(userEmail, distName, distType, prjName, prjType, environmentName, parentId, null, options,
        function (err, newJob) {
            callback(err, new TizenArchiveJob(newJob));
        });
}
module.exports.createJob = createJob;


/**
 * Initialize Tizen archive job
 * @function executeJob
 * @param {module:models/job~Job} job - job
 * @param {string} jobWorkPath - jobWorkPath
 * @param {module:core/base-server.BaseServer} server - server
 * @param {module:lib/utils.callback_error} callback - callback(error)
 * @memberOf module:models/tizen-project/project
 */
function initializeJob(job, options, callback) {
    if (job.status === 'INITIALIZED') {
        callback(null); return;
    }

    callback(null, job);
}
module.exports.initializeJob = initializeJob;


/**
 * Execute Tizen archive job
 * - it checks archive package and upload
 * @function executeJob
 * @param {module:models/job~Job} job - job
 * @param {string} jobWorkPath - jobWorkPath
 * @param {module:core/base-server.BaseServer} server - server
 * @param {module:lib/utils.callback_error} callback - callback(error)
 * @memberOf module:models/tizen-project/project
 */
module.exports.executeJob = function (job, options, callback) {
    var jobWorkPath = options.jobWorkPath;
    var monitor = options.monitor;

    var parentServerId = options.parentServerId;
    var server = dibs.getServer(parentServerId);

    async.series([
        // function (cb) {
        //     monitor.updateProgress('Checking reverse build...', cb);
        // },
        // function (cb) {
            // TODO: need to add checking reverse-build logic?
            // ReverseBuildChecker.check(job, true, cb);
            // cb(null);
        // },
        function (cb) {
            var fileName = path.basename(job.options.FILEPATH);
            var pkgPath = path.join(jobWorkPath, fileName);

            // get file
            server.dfsGetFile(pkgPath, job.options.FILEPATH, function (err) {
                if (!err) {
                    job.options.packages.push(fileName);
                }
                cb(err);
            });
        },
        function (cb) {
            monitor.updateProgress('Checking uploading...', cb);
        },
        // upload
        function (cb) {
            if (job.parentId !== null) {
                job.resultFiles = [job.options.FILEPATH];
                monitor.updateProgress('Skipped uploading', cb);
            } else if (job.options.UPLOAD) {
                upload(job, jobWorkPath, monitor, cb);
            } else {
                monitor.updateProgress('Skipped uploading', cb);
            }
        },
        function (wcb) {
            monitor.updateProgress('Uploading is done!', wcb);
        },
        function (cb) {
            monitor.updateProgress('Terminating job...', cb);
        }], function (err) {
        // NOTE. MUST strip unnecessary information for reducing object size
        //       if not, DNODE RPC cannnot receive callback
        TizenCommon.stripJob(job);

        callback(err, job);
    });
};


function upload(job, jobWorkPath, monitor, callback) {
    monitor.updateProgress('Uploading... ');

    var repoServers = dibs.getServersByType('repo');
    if (repoServers.length === 0) {
        var error = new DError('TIZENGITJOB007');
        callback(error);
        return;
    }

    // register files
    var pkgPath = path.join(jobWorkPath, path.basename(job.options.FILEPATH));
    repoServers[0].registerPackages([pkgPath],
        {
            repoType: 'tizen',
            distName: job.distName,
            userEmail: job.userEmail
        },
        function (err) {
            if (!err) {
                monitor.updateProgress('Uploading package succeeded! ', callback);
            } else {
                monitor.updateProgress({
                    log: 'Uploading package failed! ',
                    logType: 'error'
                });
                callback(err);
            }
        });
}
