"use strict"

var pathmodule = require('path');
var app = require('express')();
var http = require('http').Server(app);
var https = require('https');
var CONFIG = require( pathmodule.resolve( __dirname, "runconfig.js" ) );
const io = require("socket.io")(http, {
//  pingTimeout: 30000,
//  allowUpgrades: false,
//  serveClient: false,
//  pingInterval: 10000,
//  //transports: [ 'websocket', 'polling' ],
//  transports: [ 'polling', 'websocket' ],
  cors: {
    origin: "http://localhost:8080",
    methods: ["GET", "POST"],
    allowedHeaders: ["my-custom-header"],
    credentials: true
  },
  cookie: {
    name: "test",
    httpOnly: false,
    path: "/custom"
  }
});

const { DateTime } = require("luxon");


 var async = require("async");
const { check, validationResult } = require('express-validator');
const urlExistSync = require("url-exist-sync");

var express = require('express');
app.use(express.json());

const axios = require('axios');
axios.defaults.timeout = 30000

 const helmet = require('helmet');
app.use(helmet());

const cors = require('cors')
const whitelist = [
        'http://localhost:8080',
        'http://localhost:3080',
        'http://localhost:3081',
        'http://localhost:3082'
        ]
const corsOptions = {
  credentials: true,
  methods: ['GET', 'PUT', 'POST', 'DELETE', 'OPTIONS'],
  optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
  allowedHeaders: [
        'Content-Type',
        'Authorization',
        'X-Requested-With',
        'device-remember-token',
        'Access-Control-Allow-Origin',
        'Access-Control-Allow-Headers',
        'Origin',
        'Accept'
  ],
  origin: function(origin, callback) {
    if (whitelist.indexOf(origin) !== -1) {
      callback(null, true)
    } else {
      callback(null, true)
      //callback(new Error('Not allowed by CORS'))
    }
  }
}
app.use(cors)



// ***************************************************
//      checktoken
// ***************************************************

async function checkToken(token) {
  const agent = new https.Agent({
    rejectUnauthorized: false,
  });
  const instance =  axios.create({
    baseURL: 'https://api.swarmlab.io',
    withCredentials: true,
    rejectUnauthorized: false,
    crossdomain: true,
    httpsAgent: agent,
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'multipart/form-data',
      'Authorization': 'Bearer '+token
    }
  })
    try {
        var pipelines =  {
            "source":'ssologin'
        }
        var params = {
            pipeline: pipelines
          }

       var options = {
          headers: { 'content-type': 'application/x-www-form-urlencoded',Authorization: `Bearer ${token}` },
        };

     instance.defaults.timeout = 30000;
     const res = await instance.post('/istokenvalidsso',params,options);
        if(res.status == 200){
            //console.log("check " +JSON.stringify(res.data))
            return res.data
        }else{
            console.log("noerror: " + res)
            return res.status

        }
    }
    catch (err) {
        console.error("error: "+err);
        var error = new Object();
        error.action = '401'
        return error
    }
}


function convertDateToUTC(date) {
return new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds(),date.getUTCMilliseconds());
}

// ***************************************************
//      get pipelines
// ***************************************************

async function getpipelines(token,pipelinename) {
  const agent = new https.Agent({
    rejectUnauthorized: false,
  });
  const instance =  axios.create({
    baseURL: 'https://api.swarmlab.io',
    withCredentials: true,
    rejectUnauthorized: false,
    crossdomain: true,
    httpsAgent: agent,
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'multipart/form-data',
      'Authorization': 'Bearer '+token
    }
  })
  /*
   var params = {
            playbook: value
          }
        var options = {
          params: params,
          headers: { 'content-type': 'application/x-www-form-urlencoded',Authorization: `Bearer ${token}` },
        };

        const playbook = await api.GET('playbookCode',options);
        return playbook
*/
    try {

        var pipelines =  {
            "querytokenFilter":CONFIG.api.token,
            "filter":pipelinename
        }
        //var params = {
        //    pipeline: pipelines
        //  }
        var params = {
            querytokenFilter:CONFIG.api.token,
            filter:pipelinename
          }

       var options = {
          params: params,
          headers: { 'content-type': 'application/x-www-form-urlencoded',Authorization: `Bearer ${token}` },
        };

      //https://api.swarmlab.io/gettutorlabrooms?sort=pipelinename%7Casc&page=1&per_page=5&filter=&type=scripts&tutor=yes
     instance.defaults.timeout = 30000;
     //const res = await instance.get('/getplaygrounds',params,options);
     const res = await instance.get('/getplaygrounds',options);
        if(res.status == 200){
            return res.data
        }else{
            console.log("noerror: " + res)
            return await res.status

        }
    }
    catch (err) {
        console.error("error: "+err);
        var error = new Object();
        error.action = '401'
        return await error
    }
}

// ***************************************************
//      get user pipelines
// ***************************************************

async function getuserpipelines(token,user,swarmlabname) {
  var pipelinename = user
  const agent = new https.Agent({
    rejectUnauthorized: false,
  });
  const instance =  axios.create({
    baseURL: 'https://api.swarmlab.io',
    withCredentials: true,
    rejectUnauthorized: false,
    crossdomain: true,
    httpsAgent: agent,
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'multipart/form-data',
      'Authorization': 'Bearer '+token
    }
  })
    try {

        var pipelines =  {
            "querytokenFilter":CONFIG.api.token,
            "filter":pipelinename,
            swarmlabname:swarmlabname 
        }
        //var params = {
        //    pipeline: pipelines
        //  }
        var params = {
            querytokenFilter:CONFIG.api.token,
            filter:pipelinename,
            swarmlabname:swarmlabname 
          }

       var options = {
          params: params,
          headers: { 'content-type': 'application/x-www-form-urlencoded',Authorization: `Bearer ${token}` },
        };

     instance.defaults.timeout = 30000;
     const res = await instance.get('/getuserplaygrounds',options);
        if(res.status == 200){
            return res.data
        }else{
            console.log("noerror: " + res)
            return await res.status

        }
    }
    catch (err) {
        console.error("error: "+err);
        var error = new Object();
        error.action = '401'
        error.error = err
        return await error
    }
}


global.online='ob';
global.pipelines=[];


// ***************************************************
//      rest  get
// ***************************************************




app.get('/run', (req, res, next) => {

  (async() => { 

      var RES = new Object();
      RES.code    = req.query["action"]
      RES.token    = req.query["token"]
      RES.error = false
      RES.error_msg = "ok"
      res.json(RES)
  })()

});


// ***************************************************
//      socket
// ***************************************************

//function getSHA256ofJSON(input){
//  return   require("crypto").createHash("sha256").update(JSON.stringify(input)).digest("hex");
//}

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

function getSHA256ofJSON(data, inputEncoding, encoding){
  if (!data) {
    return '';
  }
  inputEncoding = inputEncoding || 'utf-8';
  encoding = encoding || 'hex';
  const hash = require("crypto").createHash('md5');
  return hash.update(JSON.stringify(data), inputEncoding).digest(encoding);
}





io.on('connection', s => {                                                                
        console.error('socket connection');                 

        // ------------------------------
        // --- set
        // ------------------------------
        var usersession = new Object();
        usersession.SOCKET = {};
        usersession.SOCKET.error = {};
        console.error('socket ...');
        //s.auth = false;
        s.auth = true;

        // ------------------------------
        // --- authenticate
        // ------------------------------
        s.on('authenticate', function(data){
                const token = data 
                //console.log('invalid 1 ' + token);
                console.log("check " +JSON.stringify(data))
                (async() => { 
                    //var isvalid = await checkToken(token);
                  //
                  /*
                    if(isvalid.action == 'ok'){
                        console.log("Authserver ok ", s.id + ' - ' + token);
                        usersession.SOCKET.user  = isvalid.user
                        usersession.SOCKET.scope = isvalid.scope // space delimeter
                        usersession.SOCKET.token = isvalid.token
                        s.auth = true;
                    }else{
                        console.log("Authserver no ", s.id + ' - ' + token);
                        s.auth = false;
                    }
                    */
                        s.auth = true;
                })()
        });
/*
        setTimeout(function(){
                if (!s.auth) {
                        console.log("Disconnecting timeout socket ", s.id);
                        //s.disconnect('unauthorized');
                }else{
                   var room = usersession.SOCKET.user 
                   //s.on("subscribe", function (room) {
                      s.join(room);
		                  console.log("joining rooom", s.rooms); 
                      console.log(room + ' created ')
                   // });
                }
         }, 30000);
*/

        var id = s.id                                         
        s.on('action', obj => {                                  
          console.error('from client '+ s.id + ' obj ' + obj);                    
        });                                                                       
                                                                              
});                                                                           

http.listen(3000, () => console.error('listening on http://localhost:3000/'));
console.error('socket.io example');