/**  This file will install Reactor as a service on Windows 10/11 systems.
 * 
 *   THIS FILE APPLIES TO WINDOWS SYSTEMS ONLY!
 *
 *   READ ALL INSTRUCTIONS BELOW BEFORE RUNNING THIS INSTALLER.
 *   DO NOT MODIFY THIS FILE.
 *
 *   Before running this script, install the "node-windows" package
 *   (make sure you are in the Reactor install directory when you run
 *   this command):
 *
 *       npm install node-windows --no-save
 *
 *   To install the Reactor service:
 *
 *       node install_reactor_windows_service.js -i <path> [-t <zone>]
 *
 *   where <path> is the pathname of your Reactor install directory.
 *   If your system clock is running in your local time zone, you do not
 *   need to specify -t <zone>. But, if your system clock is UTC, and your
 *   local time is *not* UTC, you must specify -t <zone>. Valid timezone
 *   names can be found at:
 *   https://grokipedia.com/page/List_of_tz_database_time_zones
 *
 *
 *   To uninstall the service:
 *
 *       node install_reactor_windows_service.js -u <path>
 *
 *   where <path> is the pathname of your Reactor install directory.
 *
 */

const path = require( 'path' );
const fs = require( 'fs' );

let REACTOR_HOME, mode, TZ;
let argv = process.argv.slice( 2 );
if ( 0 === argv.length ) {
    console.log( "To install, specify -i <path> [ -t <zone> ]" );
    console.log( "    where <path> is the location of your Reactor install directory." );
    console.log( "    You only need to specify -t <zone> if your system clock is on UTC" );
    console.log( "    but your local time is *not* UTC. The list of valid zone names is:" );
    console.log( "    https://grokipedia.com/page/List_of_tz_database_time_zones");
    console.log( "To uninstall: specify -u <path>" );
    console.log( "" );
    console.log( "Additional instructions: https://reactor.toggledbits.com/docs/Installation/" );
    return 255;
}
while ( argv.length > 0 ) {
    let arg = argv.shift();
    switch ( arg ) {
        case '-t':
            if ( argv.length < 1 ) {
                console.error( "Argument -t requires timezone name" );
                process.exit(255);
            }
            TZ = argv.shift();
            break;

        case '-i':
            if ( mode ) {
                console.error( "You can specify -i <path> or -u <path>, but not both." );
                process.exit(255);
            }
            if ( argv.length < 1 ) {
                console.error( "Argument -i requires pathname to Reactor install directory" );
                process.exit(255);
            }
            REACTOR_HOME = argv.shift();
            mode = 'i';
            break;

        case '-u':
            if ( mode ) {
                console.error( "You can specify -i <path> or -u <path>, but not both." );
                process.exit(255);
            }
            if ( argv.length < 1 ) {
                console.error( "Argument -i requires pathname to Reactor install directory" );
                process.exit(255);
            }
            REACTOR_HOME = argv.shift();
            mode = 'u';
            break;

        default:
            console.error( "Invalid argument:", arg );
            process.exit(255);
    }
}

const rp = path.resolve( REACTOR_HOME );
const ap = path.join( rp, "app.js" );
if ( ! fs.existsSync( ap ) ) {
    console.error( "Invalid path:", REACTOR_HOME );
    console.error( "Reactor's app.js file could not be found in this location." );
    console.error( "Please read this script's header for instructions." );
    process.exit(255);
}

var Service = require('node-windows').Service;

if ( "i" === mode ) {
    console.log( "Installing service to run Reactor in", rp );
    let ev = [ { name: 'REACTOR_HOME', value: rp }, { name: 'NODE_PATH', value: rp } ];
    if ( TZ ) {
        ev.push( { name: 'TZ', value: TZ } );
    }
    // console.log( "env", ev );
    var svc = new Service({
      name: 'Reactor',
      description: 'Reactor (Multi-System) Service',
      script: ap,
      nodeOptions: [],
      workingDirectory: rp,
      env: ev
    });

    // Listen for the "install" event, which indicates the
    // process is available as a service.
    svc.on('install',function(){
      console.log( "Starting Reactor service" );
      svc.start();
    });
    svc.on( 'alreadyinstalled', function() {
        console.error( "The Reactor service is already installed. Use -u <path> to uninstall." );
    });

    svc.install();
} else if ( "u" === mode ) {
    console.log( "Uninstalling Reactor service", rp );
    var svc = new Service({
      name: 'Reactor',
      script: ap,
    });

    svc.on( 'uninstall', function(){
      console.log( "Reactor service uninstalled." );
    });

    svc.uninstall();
}