

var mongoose = require('mongoose');
var timestamps = require('mongoose-time');
var serverConfig = require('../../config/v16/config');
var User = require('./User');
var Task = require('./Task');
var utils = require('../../config/v16/utils');
var messages = require('../../config/v16/messages');
var denormalize = require('mongoose-filter-denormalize').denormalize;
var ObjectId = mongoose.Schema.ObjectId;
var GetEnumsFromDB = require('../../server/services/v16/Utils/GetEnumsFromDB');
var CircularJSON = require('circular-json');
var schemaVersion = serverConfig.config.schemaVersion;
var uniqueValidator = require('mongoose-unique-validator');
var stringify = require('safe-stable-stringify');
var Schema = mongoose.Schema;
var connectorDefault = "NOT_SCHEDULED";
var OutputStatusSchema = new Schema({
    outputFormat: {
        type: String
    },
    outputFile: {
        type: String
    },
    outputResult: {
        type: String
    },
    createdTime: {
        type: String
    }
});
var JobStatusSchema = new Schema({
    inputfile: {
        type: String
    },
    outputstatuss: [OutputStatusSchema]
});

var TaskStatusSchema = new Schema({
    taskrunningstatus: {
        type: String
    },
    jobstatuss: [JobStatusSchema]
});
var RunTaskSchema = new Schema({
    taskstatuss: TaskStatusSchema,
    startTime: {
        type: String,
        default: messages.messages.NA
    },
    endTime: {
        type: String,
        default: messages.messages.NA
    },
    createdOn: {
        type: String,
        default: Date.now()
    },
    priority: {
        type: String,
        default: 1
    },
    tasktimeout: {
        type: Number,
        default: serverConfig.config.taskTimeOut
    },
    noOfRetries: {
        type: Number,
        default: 0
    },
    taskAddTime: {
        type: Number,
        default: new Date().getTime()
    },
    tasktimeoutAfter: {
        type: Number
    },
    runningtaskAddTime: {
        type: Number,
        default: new Date().getTime()
    },
    runningtasktimeoutAfter: {
        type: Number
    },
    runningtasktimeout: {
        type: Number,
        default: serverConfig.config.runningtaskTimeOut
    },
    task: {
        type: String,
        default: messages.messages.NA
    },
    user: {
        type: String,
        default: messages.messages.NA
    },
    taskoutputs: [{
        type: ObjectId,
        ref: 'taskoutputs',
        autopopulate: true
    }],
    taskoutputsstring: [{
        type: String
    }],
    status: {
        type: String,
        enum: serverConfig.config.queuestatus,
        default: connectorDefault,
        uppercase: true

    },
    userid: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'users',
        default: null
    },
    lastRunIdInformation: {
        type: String,
        uppercase: true,
        required: true,
        unique: true
    },
    user_denorm: {
        type: ObjectId,
        ref: 'users',
        default: null,
        autopopulate: true
    },
    taskid: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'tasks',
        default: null
    },
    task_denorm: {
        type: ObjectId,
        ref: 'tasks',
        default: null,
        autopopulate: true
    },
    name: {
        type: String,
        default: messages.messages.NA
    },
    cronObject: {
        type: String,
        default: messages.messages.NA
    },
    scheduleid: {
        type: String,
        default: messages.messages.NA
    },
    workerProcessPid: {
        type: String,
        default: messages.messages.NA
    },
    workerid: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'workers',
        default: null
    },
    worker_denorm: {
        type: ObjectId,
        ref: 'workers',
        default: null,
        autopopulate: true
    },
    xml: {
        type: String
    },
    __schemaVersion: {
        type: String,
        default: schemaVersion
    },
    runtask_denorm_string: {
        type: String
    }
}).plugin(timestamps());

RunTaskSchema.plugin(require('mongoose-autopopulate'));

function replacer(key, value) {
    if (key == "runtask_denorm_string") return undefined;else if (key == "__schemaVersion") return undefined;else if (key == "gen_id") return undefined;else return value;
}
RunTaskSchema.pre('init', function (next) {});
RunTaskSchema.pre('validate', function (next) {
    var user = this;
    var connectorArray = serverConfig.config.queuestatus;;

    if (user.userid === undefined || user.userid === null) {
        user.userid = serverConfig.config.DefaultId;
    }
    if (!utils.isPresentInArray(connectorArray, user.status)) {
        var err = new Error(messages.messages.INVALIDSTATUS);
        err.status = user.status;
        connectorArray = undefined;
        next(err);
    }
    connectorArray = undefined;
    return next();
});

RunTaskSchema.pre('update', function (next) {
    var user = this;
    if (this.userid === undefined || this.userid === null) {
        this.userid = serverConfig.config.DefaultId;
    }
    user.user_denorm = user.userid;
    user.task_denorm = user.taskid;
    user.worker_denorm = user.workerid;
    if (user.status === 'RUNNING') {
        var newTimeoutTime = utils.addMinutes(new Date(), serverConfig.config.runningtaskTimeOut);
        var timeouttimestamp = newTimeoutTime.getTime();
        var currentime = new Date().getTime();
        user.runningtasktimeoutAfter = timeouttimestamp;
        user.runningtaskAddTime = currentime;
        user.runningtasktimeout = serverConfig.config.runningtaskTimeOut;
        user.markModified('runningtasktimeoutAfter');
        user.markModified('runningtaskAddTime');
        user.markModified('runningtasktimeout');
    }

    /* user.markModified('user_denorm');
     user.markModified('task_denorm');
     user.markModified('worker_denorm');*/
    var serializedString = stringify(user, replacer);
    user.runtask_denorm_string = serializedString;
    //user.markModified('runtask_denorm_string');
    //user.isNew = true;
    return next();
});
RunTaskSchema.pre('save', function (next) {
    var user = this;
    var connectorArray = serverConfig.config.queuestatus;;

    if (user.userid === undefined || user.userid === null) {
        user.userid = serverConfig.config.DefaultId;
    }
    if (user.connectorType !== undefined && user.connectorType !== null && !utils.isPresentInArray(connectorArray, user.connectorType.toUpperCase())) {
        var err = new Error(messages.messages.INVALIDSTATUS);
        err.status = user.status;
        connectorArray = undefined;
        next(err);
    } else {
        user.user_denorm = user.userid;
        user.task_denorm = user.taskid;
        user.worker_denorm = user.workerid;

        user.tasktimeoutAfter = utils.addMinutes(user.created_at, user.tasktimeout);
        user.markModified('tasktimeoutAfter');
        user.markModified('user_denorm');
        user.markModified('task_denorm');
        user.markModified('worker_denorm');
        var serializedString = stringify(user, replacer);
        user.markModified('runtask_denorm_string');
        user.isNew = true;
        connectorArray = undefined;
        return next();
    }
});

RunTaskSchema.index({
    userid: 1,
    taskid: 1,
    status: 1
});
RunTaskSchema.index({
    userid: 1,
    taskid: 1,
    worker: 1
});
RunTaskSchema.plugin(uniqueValidator);
var RunTaskObject = mongoose.model('runtasks', RunTaskSchema);

module.exports = RunTaskObject;