// Modules to control application life and create native browser window
const {app, BrowserWindow, ipcMain} = require('electron')
const path = require('path')
const fs = require('fs')

// ---------------- Single instance control section begin

var gotTheLock = false;
var rootPathLength = __dirname.length - 14; // Length of "/resources/app is 14
var tooLongPath = rootPathLength > 159; 
const isInProgramFiles = __dirname.includes('Program Files');
console.log("rootPathLength=" + rootPathLength);

// ---------------- BACKEND CONTROL SECTION begin -----
const backEndRunnerClass = require('../../backend/compose').compose;
const { allowedNodeEnvironmentFlags } = require('process');
const backendConfig = JSON.parse( fs.readFileSync( path.join( __dirname, '../../backend/compose.json'), "utf-8"));
const packageName = backendConfig.packageName ? backendConfig.packageName : "(packageName not specified in config)";
const BackEndRunner = new backEndRunnerClass( { ...{ root: '{composedir}'},  ...backendConfig} );
const interval_s_min = 5;
const interval_s_max = 120;
var   runtime_s = 0;
var   interval_counter = 0;
var   interval_s_print = interval_s_min;
var   lastActivity = new Date();
var   backEndTimer = null;

function backEndCallback( reason, child, data ) {
  lastActivity = new Date();
  if (reason == 'debug') {
      console.log( new Date().toISOString() + ' ' + child + ' ' + data);
  } else {
      console.log( new Date().toISOString() + ' ' + reason.padEnd(12,' ') + child.padEnd(12,' ') + data);
  }
}
function backEndPeriodic( ) {
  runtime_s++;
  var now = new Date();
  var activity = false;
  if ((((now - lastActivity) > 900) && ((now - lastActivity) <2400)) && ( runtime_s > 4)) {
      activity = true;
      console.log("-----");
      //console.log(new Date().toISOString() + ' ' + packageName + " .....");
      interval_s_print = interval_s_min;
  }
  if ((runtime_s < 4) || (++interval_counter >= interval_s_print)|| (activity)) {
     interval_counter = 0;
     var serviceStatus = BackEndRunner._getRunningSummary( );
     console.log(new Date().toISOString() + ' ' + packageName + "  Laucher IDLE  (cycle 1/"
         + interval_s_print.toString().padStart(4,'0') + ") runtime ~ "
         + runtime_s.toString().padStart(6,' ')
         + " s. Status: " +  serviceStatus.running.length + " running, " + serviceStatus.stopped.length + " stopped");
     if(serviceStatus.running) {
         serviceStatus.running.forEach( (svc) => {
             if ((svc) && (svc.id) && (svc.pid) ) {
                console.log( '   ' + svc.id.padEnd(10,' ') + ' pid:' + svc.pid.toString().padStart(5,' ') );
             }
         });
     }
     if ( serviceStatus.stopped.length > 0) {
        // attempt restart...
        BackEndRunner.startStoppedServices();
     }
     if (interval_s_print < interval_s_max) interval_s_print += 10;
  }
}
// ---------------- BACKEND CONTROL SECTION end -----


function createWindow () {

  // webPreferences { worldSafeExecuteJavaScript: true }
  // Create the browser window.
  const mainWindow = new BrowserWindow({
    width: 1300,
    height: 800,
    minWidth:400,
    minHeight:600,
    icon: path.join(__dirname, './favicon.ico'),
    webPreferences: {
      preload: path.join(__dirname, 'preload.js'),
      worldSafeExecuteJavaScript: true,
      zoomFactor: 1.0
    }
  })
  mainWindow.setMenuBarVisibility(false);

  // Continue to handle mainWindow "close" event here
  mainWindow.on('close', function(e){
      console.log("################# mainWindow.on(close)");
      e.preventDefault();
      if ( backEndTimer != null) clearInterval( backEndTimer);
      backEndTimer = null;
      if ( BackEndRunner) BackEndRunner.stop();
      app.quit();
      process.exit(0);
      //if(!force_quit){
      //    e.preventDefault();
      //    mainWindow.hide();
      //}
  });
  // and load the index.html of the app.

  const filetypes = {
    "ncfg" : {title : "Save NETCO Transport file",         filters: [ {name : "NETCO Transport File",   extensions : ["ncfg"]} ]},
    "ncl"  : {title : "Save NETCO Channel List file",      filters: [ {name : "NETCO Channel List",     extensions : ["ncl"]} ]},
    "txt"  : {title : "Save NETCO Text Report",            filters: [ {name : "Text File",              extensions : ["txt"]} ]},
    "up"   : {title : "Save NETCO User Permissions File",  filters: [ {name : "NETCO User Permissions", extensions : ["up"]}  ]}
}
  mainWindow.webContents.session.on('will-download', (event, item, webContents) => {
    const extension = path.extname(item.getFilename()).replace(/^\./, '').toLowerCase();
    if ( filetypes[extension] ){
      item.setSaveDialogOptions({
           title : filetypes[extension].title,
           filters: filetypes[extension].filters
      });
    }
  });


  let win = mainWindow; // BrowserWindow.getAllWindows()[0];
  //win.webContents.setZoomFactor(1.0);
  // Upper Limit is working of 500 %
  win.webContents
      .setVisualZoomLevelLimits(1, 5)
      .then(console.log("Zoom Levels Have been Set between 100% and 500%"))
      .catch((err) => console.log(err));


  win.webContents.on('did-finish-load', () => {
    win.webContents.setZoomFactor(1)
  });

  win.webContents.on("zoom-changed", (event, zoomDirection) => {
      console.log(zoomDirection);
      var currentZoom = win.webContents.getZoomFactor();
      console.log("Current Zoom Factor - ", currentZoom);
      console.log("Current Zoom Level at - ", win.webContents.zoomLevel);
      if (zoomDirection === "in") {    // win.webContents.setZoomFactor(currentZoom + 0.20);
          if ( currentZoom < 5.0) {
            win.webContents.zoomFactor = currentZoom + 0.1;
            console.log("Zoom Factor Increased to - ", win.webContents.zoomFactor * 100, "%");
          }
      }
      if (zoomDirection === "out") {
          // win.webContents.setZoomFactor(currentZoom - 0.20);
          if ( currentZoom >= 0.3) {
            win.webContents.zoomFactor = currentZoom - 0.1;
            console.log("Zoom Factor Decreased to - ", win.webContents.zoomFactor * 100, "%");
          }
      }
  });

    if (gotTheLock) {
      if (tooLongPath || isInProgramFiles) {
        mainWindow.loadFile('error.html');
        ipcMain.handle('get-error-info', () => {
          return {
            errorType: isInProgramFiles ? "programFiles" : "longPath",
            pathLength: __dirname.length
          };
        });
      } else {
        mainWindow.loadFile('index.html');
      }
    } else {
      mainWindow.loadFile('error.html');
      ipcMain.handle('get-error-info', () => {
        return { errorType: "singleInstance" };
      });
    }
  // mainWindow.loadURL('http://localhost:8080/netco/login');


  // Open the DevTools.
  //mainWindow.webContents.openDevTools()
}

// Do not run if this is second instance i.e. allow just single instance
gotTheLock = app.requestSingleInstanceLock()
if (!gotTheLock) {
  //app.quit();
  //return;
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {

  // ------ BACKEND SERVICES start services - only if first instance
  if (gotTheLock) {
    var cwd = process.cwd();
    process.chdir( path.join(__dirname, '../../backend'));
    BackEndRunner.startServices( backEndCallback );
    backEndTimer = setInterval( () => { backEndPeriodic()}, 1000);
    process.chdir(cwd);
  }
  // ------ BACKEND SERVICES ...start finishes

  //  create the main window
  createWindow()
  app.on('activate', function () {
      // On macOS it's common to re-create a window in the app when the
      // dock icon is clicked and there are no other windows open.
      if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
})

app.on('close', function ( ) {
  console.log("################# app.on(close)");
  // The dialog box below will open, instead of your app closing.
  require('dialog').showMessageBox({
    message: "Close button has been pressed!",
    buttons: ["OK"]
  });
});
// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', function () {
    console.log("################# app.on(window-all-closed");
    // BackEndRunner.stop();
    if (process.platform !== 'darwin') app.quit()
})

// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
