'use strict';
const express = require('express')
const fileUpload = require('express-fileupload');
let request = require('request')
const process = require('process')

const app = express()
let port = 5000, resource_id, functionHash, runtime, idleTime = 60, flagFirstRequest = true
let waitTime

resource_id = process.argv[2]
functionHash = process.argv[3]
port = process.argv[4]
runtime = process.argv[5]
request = request.defaults({
    headers: { 'x-resource-id': resource_id }
});

let kafka = require('kafka-node'),
    Producer = kafka.Producer,
    client = new kafka.KafkaClient({
        kafkaHost: process.argv[6],
        autoConnect: true
    }),
    producer = new Producer(client)

app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(fileUpload())

let lastRequest = Date.now(), totalRequest = 0
app.post('/serverless/function/execute/', (req, res) => {
    if (flagFirstRequest) {
        waitTime = Date.now() - waitTime
        flagFirstRequest = false
        producer.send(
        [{
            topic: "test",
            messages: JSON.stringify({
                functionHash, portExternal: port,
                runtime, resource_id, entity_id: process.pid,
                total_request: totalRequest, wait_time: waitTime
            }),
            "status": true
        }], () => { })
    }
    let payload = req.body
    lastRequest = Date.now()
    totalRequest++
    executor(payload).then((result) => {
        res.json(result)
        idleTime = 0
    })
})

app.post('/serverless/function/timeout', (req, res) => {
    console.log(req.body);
    
    let idleTime = parseInt(req.body.timeout)
    console.log("Idle time set to: ", idleTime);
    res.json({
        status: "success"
    })
})

async function executor(payload) {
    return new Promise((resolve, reject) => {
    })
}

app.listen(port, () => {
    console.log(`Resource ${resource_id} Server listening on port ${port}!`)
    producer.send(
    [{
        topic: "deployed",
        messages: JSON.stringify({ functionHash, portExternal: port, 
            runtime, resource_id, entity_id: process.pid}),
        "status": true
    }], () => { })
    waitTime = Date.now()
})

function shouldDie() {
    
    if (Date.now() - lastRequest > idleTime * 1000) {
        let message = JSON.stringify({
            functionHash, portExternal: port,
            runtime, resource_id, entity_id: process.pid,
            total_request: totalRequest, wait_time: waitTime
        })

        console.log("Idle for too long. Exiting");
        producer.send(
            [
                {topic: "removeWorker", messages: message }
            ], (err, data) => {
                if (err)
                    console.log(err);
                    
                console.log("Ending worker for function", functionHash, "resource_id", resource_id);
                process.exit(0)
            })
        
    }
}

setInterval(shouldDie, 1000);
