
var myArgs = process.argv.slice(2);

if ( myArgs.length < 3 ) {
    console.log("Missing args", myArgs);
    process.exit(0);
}

const db = require('qmi-cloud-common/mongo');
const sendEmail = require("qmi-cloud-common/send-email");
const moment = require('moment');
const fetch = require('node-fetch');


const IS_REAL = myArgs[2] !== 'test';
const STOPPED_PERIOD = myArgs[1]; //Days
const STOPPED_LIMIT_HOURS_WARNING = 24*(STOPPED_PERIOD-2); //Hours
const STOPPED_LIMIT_HOURS_STOP = 24*STOPPED_PERIOD; //Hours
const API_KEY = process.env.API_KEY;
const SERVER_URL = "http://localhost:3000";

if ( !API_KEY ) {
    console.log("Missing env API_KEY");
    process.exit(0);
}

async function postDestroy(provision) {

    const userId = provision.user._id.toString();
    const provId = provision._id.toString();
    
    return fetch(`${SERVER_URL}/api/v1/users/${userId}/provisions/${provId}/destroy?apiKey=${API_KEY}`, {
        method: 'POST',
        headers:{
            'Content-Type': 'application/json'
        }
    })
	.then(res => res.json())
    .then(json => console.log(json));
}


function timeRunning(p) {
    let totalStopTime = Math.abs(new Date().getTime() - new Date(p.stoppedFrom).getTime());
    let duration = moment.duration(totalStopTime);
    p.duration = {
        hours: Math.floor(duration.asHours()),
        complete: Math.floor(duration.asDays()) +"d "+duration.hours()+"h "+duration.minutes()
    };
}

async function asyncForEach(array, callback) {
    for (let index = 0; index < array.length; index++) {
        await callback(array[index], index, array);
    }
}

async function init(type) {
    var limit, cb;
    var filter = {
        "isDestroyed":false, 
        "isDeleted": false, 
        "statusVms": "Stopped"
    };
    if ( type === "warning" ) {
        limit = STOPPED_LIMIT_HOURS_WARNING;  
        filter.pendingNextAction = {$ne: "destroy"};
        cb = doSendEmailDestroyWarning;
    } else if ( type === "exec" ) {
        limit = STOPPED_LIMIT_HOURS_STOP;
        filter.pendingNextAction = "destroy";
        cb = doDestroy;
    } else {
        console.log("Invalid 'type'. Do nothing.");
        return;
    }

    let provisions = await db.provision.get(filter);
    let scenarios = await db.scenario.get();

    await asyncForEach(provisions.results, async function(p)  {
        var _scenario = scenarios.results.filter(s=>{
            return s.name === p.scenario
        });
        if ( _scenario.length ){
            p._scenario = _scenario[0];
        }
        timeRunning(p);
        if (!IS_REAL) {
            console.log(`${p._id} - limit: ${limit} hs - actual duration: ${p.duration.hours} hs`);
        }
        if ( p.duration && p.duration.hours >= limit) {
            await cb(p);
        }
    });
}

const doSendEmailDestroyWarning = async function(p) {
    if ( p.pendingNextAction === 'destroy') {
        console.log(`Warning email Destroy already sent. Wait for pending action to complete.`);
    } else {
        let msg = `Send warning DESTROY email - ${p.user.displayName} (${p.user.upn}) about provision '${p._scenario.title}' (${p._id}) being 'Inactive' more than ${STOPPED_LIMIT_HOURS_WARNING} hours (exactly ${p.duration.complete})`;
        console.log(msg);  
        if ( IS_REAL ) {
            await db.provision.update(p._id, {"pendingNextAction": "destroy"});
            await sendEmail.sendWillDestroyIn24(p, p._scenario);
            await db.notification.add({ provision: p._id.toString(), type: 'warningDestroy', message: msg });    
        }        
    }  
};

const doDestroy = async function(p) {
    try {
        let msg = `Provision destroyed - ${p.user.displayName} (${p.user.upn}) about provision '${p._scenario.title}' (${p._id}) being 'Inactive' more than ${STOPPED_LIMIT_HOURS_STOP} hours (exactly ${p.duration.complete})`
        console.log(msg);
        if ( IS_REAL ) {         
            await postDestroy(p);
            await db.notification.add({ provision: p._id.toString(), type: 'destroy', message: msg });
        }
    } catch (error) {
        console.log("doDestroy Error", error);
    }    
};

function check(type) {
    init(type).then(function(){
        db.mongoose.connection.close()
        process.exit(0);
        
    }).catch(function(e){
        db.mongoose.connection.close()
        console.log("Error", e);
        process.exit(0);
    });
}


// --------------------------------
switch (myArgs[0]) {
    case 'warning':
        check("warning");
        break;
    case 'exec':
        check("exec");
        break;
    default:
        console.log('Sorry, that is not something I know how to do.');
        process.exit(0);
}



