const db = require('qmi-cloud-common/mongo');
const path = require('path');
const PROJECT_PATH = process.env.PROJECT_PATH;
const tf = require("./docker/tf");
const azure = require("./docker/azure");
const sendEmail = require("qmi-cloud-common/send-email");

module.exports = async function(job) {
        
    var prov = await db.provision.update(job.data.id, {
        "status": "initializing", 
        "jobId": job.id, 
        "logFile": path.join('/logs', 'provision', `${job.data.id}.log`),
        "path": path.join(PROJECT_PATH, '..', 'qmi-cloud-provisions', `${job.data.scenario}_${job.data.id}`)
    });

    if ( !prov ) {
        console.log(`Error: Not found Provision object in Database (it should exist!), provisionId is: ${job.data.id}` );
        return Promise.reject({"success": false, "err": "Not found Provision object in Worker"});
    }

    // TERRAFORM INIT
    return tf.init(prov)
    .then(async function(res) {
        if ( res.statusCode ===  1 ) {
            console.log("Error at INIT");
            return Promise.reject({"success": false, "error": "Error at Terraform Init", provStatus: "error_init"}); 
        } else {
            // TERRAFORM PLAN
            return tf.plan(prov, job.data._scenario);
        }      
    } )
    .then( async function(res) {
        if ( res.statusCode === 1 ) {
            console.log("Error at PLAN");
            return Promise.reject({"success": false, "error": "Error at Terraform Plan", provStatus: "error_plan"}); 
        } else {
            return await db.provision.update(prov._id,{"status": "provisioning", "statusVms": "Running", "runningFrom": new Date(), "runningTime": 0, "countExtend": 0});
        }
    } ).then( function(prov) {
        // TERRAFORM APPLY
        return tf.apply(prov);
    } ).then( async function(res) {
        if ( res.statusCode === 1 ) {
            console.log("Error at APPLY");
        }
        var status = ( res.output.indexOf("Error:") !== -1 )? "error" : "provisioned";
        return await db.provision.update(prov._id, {"status": status});
    } ).then( async function(prov) {
        return tf.outputs(prov).then( async function(outputs){
            return await db.provision.update(prov._id, {"outputs": outputs});
        });
    } ).then( async function(prov) {
        // Application Gateway assign policy
        return azure.appgateway(prov, job.data._scenario);
    } ).then( async function(prov) {
        // Create Image
        return azure.createimage(prov, job.data._scenario);
    } ).then( function(prov) {
        if (prov.status === "provisioned") {
            sendEmail.send(prov, job.data._scenario);
        } else {
            sendEmail.sendError(prov, job.data._scenario);
        }
        return Promise.resolve({"success": true, provMongo: prov});
    } ).catch( function(err) {
        console.log("Provision: error", err);
        db.provision.update(prov._id, {"status": err.provStatus? err.provStatus : 'error'});
        sendEmail.sendError(prov, job.data._scenario);
        return Promise.reject({"success": false, "error": err});
    } );
}