const fs = require('fs');
const fse = require('fs-extra');
const path = require('path');
const { execFile } = require('child_process');
const moment = require('moment');
const axios = require('axios');
const https = require('https');
const inquirer = require('inquirer');
const envfile = require('envfile');

console.log('Script started');
if (typeof process.argv[2] != 'undefined') {
    switch (process.argv[2]) {
        case 'apitest':
            const rmsUiUrl = 'https://rms-dev.darbalwatan.com';
            const rmsUser = 'sposx';
            const rmsPass = 'sposx';
            const rmsApiUrl = rmsUiUrl+'/api/v1';
            const rmsApiKey = 'jpIlK8YWTllSgs4TQEmgeM2pT87ms5IlYabZNdqoqCT59gZXpPwEAXRT13AbLJKqxriWVx3wcp3hkPfgWqnBSupy7VjlJumf8TXiAVPETvzydONkbR047muJgvKdFP46';
            const apiTimeout = 1000;
            const apiRetrys = 0;            // 3
            const apiConcurrency = 10;
            const concurrencyTimeout = 0;   // 500
            const cartId = '4017823f-3149-4be3-918a-4f32b6b10146';
            const dateTimeFormat = 'DD/MM/YY HH:mm';

            console.log('APITEST api timeout', apiTimeout, 'api retrys', apiRetrys, 'concurrency', apiConcurrency, 'concurrency timeout', concurrencyTimeout);
            apiCall();

            async function apiCall() {
                try {
                    let reservationLogin;
                    if (apiRetrys > 0) {
                        reservationLogin = await retryCall('post', rmsApiUrl+'/login', {userName: rmsUser, password: rmsPass}, {timeout: apiTimeout, headers: {'Authorization': 'ApiKey '+rmsApiKey}, httpsAgent: new https.Agent({rejectUnauthorized: false})});
                    } else {
                        reservationLogin = await axios.post(rmsApiUrl+'/login', {userName: rmsUser, password: rmsPass}, {timeout: apiTimeout, headers: {'Authorization': 'ApiKey '+rmsApiKey}, httpsAgent: new https.Agent({rejectUnauthorized: false})}).catch((err) => { return err.response; });
                    }
                    console.log('reservationLogin', reservationLogin.data.sessionId);

                    if (reservationLogin.data) {
                        let concurrency = 0;
                        while (concurrency < apiConcurrency) {
                            if (concurrencyTimeout > 0) {
                                await new Promise((r) => setTimeout(r, concurrencyTimeout));
                            }
                            let getCart;
                            if (apiRetrys > 0) {
                                getCart = await retryCall('get', rmsApiUrl+'/carts/'+cartId, {timeout: apiTimeout, headers: {'Authorization': reservationLogin.data.sessionId}, httpsAgent: new https.Agent({rejectUnauthorized: false})});
                            } else {
                                getCart = await axios.get(rmsApiUrl+'/carts/'+cartId, {timeout: apiTimeout, headers: {'Authorization': reservationLogin.data.sessionId}, httpsAgent: new https.Agent({rejectUnauthorized: false})}).catch((err) => { return err.response; });
                            }
                            concurrency++;
                            console.log((concurrency).toString().padStart(2, '0'), 'getCart', moment.utc(getCart.data.initializedOn).format(dateTimeFormat), getCart.data.travelFlexibilityType, getCart.data.travelType, getCart.data.price, getCart.data.status);
                        }
                    }
                } catch (err) {
                    console.error(err);
                }
            }

            async function retryCall(method, endpoint, data, options) {
                var retry = 0;
                var retrys = apiRetrys;
                var response;

                while (!response && retrys-- > 0) {
                    if (retry > 0) {
                        console.log('retrys', retry);
                    }
                    response = await axios[method](endpoint, data, options).catch((err) => { return err.response; });
                    retry++;
                }

                return response;
            }
        break;
        case 'apiscript':
            const configFile = envfile.parse(fs.readFileSync(path.join(process.cwd(), 'configs', '.env')));
            const apiUrl = configFile.PROTOCOL + '://' + configFile.HOST + ':' + configFile.PORT_BACKEND + '/api/';
            (async function () {
                try {
                    const scripts = [
                        'serialPortModuleFix',
                        'softwarePkgSwitch',
                        'addToDatabase',
                        'removeFromDatabase',
                        'upgradeDatabase',
                        'addToPeripheralsFile',
                        'addToEnvFile',
                        'deleteData',
                        'registerBusinessPremise'
                    ];
                    let choices = [];
                    let script = {};
                    for (var i=0; i<scripts.length; i++) {
                        choices.push({name: scripts[i]});
                        script[scripts[i]] = 'false';
                    }
                    inquirer.prompt([
                        {
                            type: 'checkbox',
                            name: 'scripts',
                            message: 'Please select scripts to run:',
                            choices: choices,
                            default: 'None'
                        }
                    ])
                    .then(async (answers) => {
                        for (var i=0; i<answers.scripts.length; i++) {
                            script[answers.scripts[i]] = 'true';
                        }
                        if (answers.scripts.length > 0) {
                            await axios.post(apiUrl+'peripherals/scripts', script);
                        }
                    });
                } catch (err) {
                    console.error(err);
                }
            })();
        break;
        default:
            console.log('No', process.argv[2], 'script');
    }
} else {
    console.log('No script argument, available scripts:', ['apitest', 'apiscript']);
}
