const Express = require('express');
const pug = require('pug');
const fs = require("fs");
const readline = require("readline");
const ping = require('ping');
const ldevices = require("local-devices");

const app = Express();
const port = 3333;
const version = 1.1;

app.use( Express.json() );
app.use( Express.urlencoded( {extended: true } ) );
app.disable( 'x-powered-by' );

app.set( 'views', __dirname + '/views' );
app.set( 'view engine', 'pug' );

app.get( '/', async ( req, res ) => {
    res.send( pug.renderFile( 'views/index.pug', { } ) );
    res.end();
} );


/** API **/
const apiResponse = {
    "api-name": "network-devices",
    "api-version": version,
    "api-author": "Tobias Hopp",
    "status": 200,
    data: null
};

app.get( '/api/getDeviceStatus/:ipAddress', async ( req, res ) => {
    console.log( 'Loading device status for ' + req.params.ipAddress + '...' );
    let ping_response = await ping.promise.probe(req.params.ipAddress, {
        timeout: 5,
        extra: ['-i', '1'],
    });

    let response = apiResponse;
    response.status = 200;
    res.status(200);
    let data;

    if( ping_response.alive )
    {
        console.log( "Device is online(" + ping_response.time + " ms)!" );
        data = { online: true, host: ping_response.host, time: ping_response.time, avg: ping_response.avg }
    }
    else
    {
        console.log( "Device might be offline... trying another method...");
        // try with another method
        // Find a single device by ip address.
        let device = await ldevices(req.params.ipAddress);
        if( !device )
        {
            console.log( "Device is offline!" );
            data = { online: false, host: ping_response.host, time: ping_response.time, avg: ping_response.avg }
        }
        else
        {
            console.log( "Device is online(unknown ms)!" );
            data = { online: true, host: device.name, time: "unknown", avg: "unknown" }
        }
    }

    response.data = data;

    res.json( response );

    res.end();
} );


app.get( '/api/getDevices', async ( req, res ) => {
    // Read the dnsmasq file
    console.log( 'Loading all devices...' );

    const fileStream = fs.createReadStream('/var/lib/misc/dnsmasq.leases' );
    const rl = readline.createInterface( { input: fileStream, crlfDelay: Infinity } );

    let data = [];
    for await ( const nline of rl )
    {
        let thisData = {};
        let line = nline.substr( nline.indexOf( ' ' ) +1 )
        thisData.macAddress = line.substr( 0, line.indexOf( ' ' ) );
        thisData.ipAddress = line.substr( thisData.macAddress.length +1, line.substr( thisData.macAddress.length+1 ).indexOf( ' ') );
        thisData.hostname = line.substr( thisData.macAddress.length + thisData.ipAddress.length +2, line.length-1 );
       /* if( thisData.hostname == 'unknown' || thisData.hostname.startsWith( '*' ) || thisData.hostname == '' )
        {
            let device = await ldevices(req.params.ipAddress);
            if( !device )
            {
                thisData.hostname = device.name;
            }
        }*/
        //console.log( nline );
        data.push( thisData );
    }



    let response = apiResponse;
    response.status = 200;
    res.status(200);

    response.data = data;
    res.json( response );

    res.end();
} );


app.get( '*', ( req, res ) => {
    res.status( 404 ).send( "not found" );
    res.end();
} );

app.listen( port, () => { console.log( "Server started!" )} );
