const express = require('express')
const router = express.Router()
const db = require('qmi-cloud-common/mongo');
const moment = require('moment');
const azurecli = require('qmi-cloud-common/azurecli');

const CACHED_PERIOD = 30; //minutes
var cachedTime;
var cachedTimeVms;
var cachedStats;
var cachedVms;
/**
 * @swagger
 * /stats:
 *    get:
 *      description: Get overall stats
 *      summary: Get overall stats
 *      produces:
 *        - application/json
 *      responses:
 *        200:
 *          description: Stats
 *        404:
 *          description: Not found
 *        
 */
router.get('/', async (req, res, next) => {
  try {
    var now = new Date().getTime();
    var nowMinus5mins = now - CACHED_PERIOD*60*1000;

    if ( (!req.query.disablecache || req.query.disablecache === 'no') && cachedStats && cachedTime && cachedTime > nowMinus5mins ) {
      console.log("APIStats# Stats: return cached value");
      cachedTime = now;
      return res.json(cachedStats);
    
    } else {
      console.log("APIStats# Stats: new value");
      let filterActiveP = { "isDestroyed": false, "status": "provisioned" };
      let filterPRunning = { "isDestroyed": false, "status": "provisioned", "statusVms" : "Running" };
      let initCurrentMonth = moment().startOf('month');
      let initLastMonth = moment(initCurrentMonth).add(-1, 'months');
      let today = moment();
      let todayLastMonth = moment().add(-1, "months");
      let filterTotalPCurrentMonth = { "status": "provisioned", "created": {
        $gte: initCurrentMonth.toISOString(), 
        $lt: today.toISOString()
      } };
      let filterTotalPLastMonth = { "status": "provisioned", "created": {
        $gte: initLastMonth.toISOString(), 
        $lt: todayLastMonth.toISOString()
      } };

      //Counts
      let totalActiveP = await db.provision.count(filterActiveP);
      let totalCPRunning = await db.provision.count(filterPRunning);
      
      let totalPCurrentmonth = await db.provision.count(filterTotalPCurrentMonth);
      let totalPLastmonth = await db.provision.count(filterTotalPLastMonth);
      
      let totalUsers = await db.user.count({});
      let totalAuthUsers = await db.user.count({
        "lastLogin": {$gte: moment().add(-12, "hours").toISOString()}
      });
      let totalScenarios = await db.scenario.count({"isDisabled":false, "isAdminOnly": false});
      
      cachedStats = {
        provisions: {
          active: totalActiveP,
          running: totalCPRunning,
          totalCurrentMonthPeriod: totalPCurrentmonth,
          totalLastMonthPerdiod:totalPLastmonth
        },
        users: {
          total: totalUsers,
          activeNow: totalAuthUsers,
          active7days: await db.user.count({
            "lastLogin": {$gte: moment().add(-7, "days").toISOString()}
          }),
          active30days: await db.user.count({
            "lastLogin": {$gte: moment().add(-30, "days").toISOString()}
          })
        },
        scenarios: {
          total: totalScenarios
        }
      };
      cachedTime = now;

      return res.json(cachedStats);

    }

  } catch (error) {
    next(error);
  }
});

function appendResult(list, output ){

  list.forEach(v=>{
    if ( v.tags && v.tags["QMI_user"] ) {
      if (v.location) {
        if ( !output.locations[v.location] ) {
          output.locations[v.location] = 0;
        }
        output.locations[v.location] += 1;
      }

      if (v.storageProfile && v.storageProfile.osDisk && v.storageProfile.osDisk.osType) {
        if ( !output.types[v.storageProfile.osDisk.osType] ) {
          output.types[v.storageProfile.osDisk.osType] = 0;
        }
        output.types[v.storageProfile.osDisk.osType] += 1;
      }

      output.out.push(v);

    }
    
  });

  return output;
}

/**
 * @swagger
 * /stats/vms:
 *    get:
 *      description: List azure vms
 *      summary: List azure vms
 *      produces:
 *        - application/json
 *      responses:
 *        200:
 *          description: Stats
 *        404:
 *          description: Not found
 *        
 */
router.get('/vms', async (req, res, next) => {

  try {

    var now = new Date().getTime();
    var nowMinus5mins = now - CACHED_PERIOD*60*1000;

    if ( (!req.query.disablecache || req.query.disablecache === 'no') && cachedVms && cachedTimeVms && cachedTimeVms > nowMinus5mins ) {
      console.log("APIStats# VMs: return cached value");
      cachedTimeVms = now;
      return res.json(cachedVms);
    
    } else {
      console.log("APIStats# VMs: new value");
      var output = {
        out : [],
        locations: {
          "eastus": 0,
          "westeurope": 0,
          "southeastasia": 0
        },
        types: {
          "Windows": 0,
          "Linux": 0
        }
      }

      var result = await azurecli.getAllVms();
      output = appendResult(result, output);
      
      if ( result.nextLink ) {
        console.log("There is a second page");
        
        result = await azurecli.getAllVmsNext(result.nextLink);
        output = appendResult(result, output);
        
        if ( result.nextLink ) {
          console.log("There is a third page");
          
          result = await azurecli.getAllVmsNext(result.nextLink);
          output = appendResult(result, output);
          
          if ( result.nextLink ) {
            console.log("There is a forth page");

            result = await azurecli.getAllVmsNext(result.nextLink);
            output = appendResult(result, output);

            if ( result.nextLink ) {
              console.log("There is a fifth page");
              
              result = await azurecli.getAllVmsNext(result.nextLink);
              output = appendResult(result, output);

              if ( result.nextLink ) {
                console.log("There is a sixth page");
                
                result = await azurecli.getAllVmsNext(result.nextLink);
                output = appendResult(result, output);

                if ( result.nextLink ) {
                  console.log("There is a seventh page");
                }
    
              }
            }
          }
        }
      }    
      
      cachedTimeVms = now;
      cachedVms = {
        total: output.out.length,
        locations: output.locations,
        types: output.types
      };

      return res.json(cachedVms);

    }

  } catch (error) {
    next(error);
  }
});

module.exports = router;