#!/usr/bin/python3
# LAVA Controls RPI - Copyright 2019 Lucid Networks - Stephen Loeckle

import socket
import binascii
import codecs
import logging
import os
import pwd
import datetime
import collections
import configparser
import argparse
import serial
import fcntl
from time import time, sleep
from multiprocessing import Process, Queue, current_process
from lavacontrolslibrpi import readdata, senddata, CoreDisplaySettings, DisplayInfo, Input, Volume

uid = pwd.getpwnam('lavacontrols-rpi')[2]
os.setuid(uid)

outputargs = {}

outputargs['debugoutput'] = 0
outputargs['modelserialoutput'] = 0
outputargs['firmwareoutput'] = 0
outputargs['tempoutput'] = 0
outputargs['inputoutput'] = 0
outputargs['tileoutput'] = 0
outputargs['poweroutput'] = 0
outputargs['volumeoutput'] = 0

PORT = 7142

def DisplayWorker(sysinfo, outputargs):
            name = current_process().name
            ts = time()
#            output = [0,1,2,3,4,5,6,7,8]
            output = {}
            now = str(datetime.datetime.now())
            if outputargs['debugoutput'] == 1:
                print("{0} Setting up network socket {1} to {2}".format(name,ip))
                output[0]=("{0} Work started: {1}".format(name,now))
                output[1]=("{0} Setting up network socket {1}".format(name,socketid))
            if outputargs['debugoutput'] == 1:
                output[2]=("{0} Connecting to network socket".format(name))
            if outputargs['debugoutput'] == 1:
                output[3]=("{0} Beginning to send data to network socket".format(name))
            cmd = (b"\x01\x30\x2A\x30\x43\x30\x36\x02\x30\x32\x33\x45\x03\x1A\x0D")
            senddata(sysinfo, cmd)
            hexresponse = readdata(sysinfo)
#            hexresponse = binascii.b2a_hex(response)
            if hexresponse == '01303041443132023030303233453030303036343030303103700d':
                displayid = 1
            elif hexresponse == '01303042443132023030303233453030303036343030303203700d':
                displayid = 2
            elif hexresponse == '01303043443132023030303233453030303036343030303303700d':
                displayid = 3
            elif hexresponse == '01303044443132023030303233453030303036343030303403700d':
                displayid = 4
            elif hexresponse == '01303045443132023030303233453030303036343030303503700d':
                displayid = 5
            elif hexresponse == '01303046443132023030303233453030303036343030303603700d':
                displayid = 6
            elif hexresponse == '01303047443132023030303233453030303036343030303703700d':
                displayid = 7
            elif hexresponse == '01303048443132023030303233453030303036343030303803700d':
                displayid = 8
            elif hexresponse == '01303049443132023030303233453030303036343030303903700d':
                displayid = 9
            elif hexresponse == '0130304a4431320230303032334530303030363430303041030b0d':
                displayid = 10
            elif hexresponse == '0130304b443132023030303233453030303036343030304203090d':
                displayid = 11
            elif hexresponse == '0130304c4431320230303032334530303030363430303043030f0d':
                displayid = 12
            else:
                displayid = 1

            dispconn = DisplayInfo(displayid,sysinfo)

            if outputargs['debugoutput'] == 1:
                output[4]=('    Internal Process: %s' % name)

            output[5]=('    ID: %d' % displayid)
            if outputargs['modelserialoutput'] == 1:
                model = dispconn.getmodel()
                serial = dispconn.getserial()
                output[6]=('    Model: %s' % model)
                output[7]=('    Serial: %s' % serial)
            if outputargs['firmwareoutput'] == 1:
                firmware1,firmware2,firmware3,firmware4 = dispconn.getfirmware()
                output[8]=('    Firmware1: %s' % firmware1)
                output[9]=('    Firmware2: %s' % firmware2)
                output[10]=('    Firmware3: %s' % firmware3)
                output[11]=('    Firmware4: %s' % firmware4)
            if outputargs['tempoutput'] == 1:
                temperature1,temperature2,temperature3,meantemperature = dispconn.gettemperature()
                output[12]=('    Temp1: %s' % temperature1)
                output[13]=('    Temp2: %s' % temperature2)
                output[14]=('    Temp3: %s' % temperature3)
                output[15]=('    Avg. Temp: %s' % meantemperature)
#                s.close()
#                sleep(0.25)
#                s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#                s.connect((ip, port))

            inputconn = Input(displayid,sysinfo)
            volconn = Volume(displayid,sysinfo)
            coreconn = CoreDisplaySettings(displayid,sysinfo)

            if outputargs['inputoutput'] == 1:
                input = inputconn.getinput()
                output[16]=('    Input: %s' % input)
            if outputargs['poweroutput'] == 1:
                power = coreconn.getpower()
                output[17]=('    Power Status: %s' % power)
            if outputargs['volumeoutput'] == 1:
                volume = volconn.getvolume()
                output[18]=('    Volume Level: %s' % volume)
            if outputargs['debugoutput'] == 1:
                output[19]=('Process Took {}'.format(time() - ts))
                now = datetime.datetime.now()
                output[20]=("{0} Work finished: {1}".format(name,str(now)))
            if outputargs['debugoutput'] == 1:
                output[21]=("{0} Closing network socket {1}".format(name,socketid))
            if outputargs['debugoutput'] == 1:
                output[22]=("{0} Closed network socket {1}".format(name,socketid))
            return(output)

def main():

    parser = argparse.ArgumentParser(description='LAVA Controls - getdisplaystatus')
    parser.add_argument('-a',action="store_true", default=False, dest='all', help = 'All Available Output')
    parser.add_argument('-d', action="store_true", default=False, dest='debug', help = 'Debug output')
    parser.add_argument('-f',action="store_true", default=False, dest='firmware', help = 'Firmware Output Only')
    parser.add_argument('-in', action="store_true", default=False, dest='input', help = 'Input Status Output Only')
    parser.add_argument('-ms', action="store_true", default=False, dest='ms', help = 'Model and Serial Output Only')
    parser.add_argument('-p',action="store_true", default=False, dest='power', help = 'Power Status Output Only')
    parser.add_argument('-pdcomms',action="store_true", default=False, dest='pdcomms', help = 'Output PD Comms Config')
    parser.add_argument('-t',action="store_true", default=False, dest='tile', help = 'Tile Status Output Only')
    parser.add_argument('-temp',action="store_true", default=False, dest='temp', help = 'Temp Status Output Only')
    parser.add_argument('-v',action="store_true", default=False, dest='volume', help = 'Volume Status Output Only')
    cliargs = parser.parse_args()

    if cliargs.debug:
        logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        logging.getLogger('requests').setLevel(logging.CRITICAL)
        logger = logging.getLogger(__name__)
        outputargs['debugoutput'] = 1
    else:
        logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        logging.getLogger('requests').setLevel(logging.CRITICAL)
        logger = logging.getLogger(__name__)
        outputargs['debugoutput'] = 0

    if cliargs.all:
        outputargs['modelserialoutput'] = 1
        outputargs['firmwareoutput'] = 1
        outputargs['tempoutput'] = 1
        outputargs['inputoutput'] = 1
        outputargs['tileoutput'] = 1
        outputargs['poweroutput'] = 1
        outputargs['volumeoutput'] = 1

    if cliargs.firmware:
        outputargs['firmwareoutput'] = 1

    if cliargs.input:
        outputargs['inputoutput'] = 1

    if cliargs.ms:
        outputargs['modelserialoutput'] = 1

    if cliargs.pdcomms:
        outputargs['pdcommsoutput'] = 1

    if cliargs.power:
        outputargs['poweroutput'] = 1

    if cliargs.tile:
        outputargs['tileoutput'] = 1
        
    if cliargs.temp:
        outputargs['tempoutput'] = 1

    if cliargs.volume:
        outputargs['volumeoutput'] = 1

    config = configparser.ConfigParser()
    config.read(['/etc/lavacontrols-rpi/lavacontrols-rpi.conf'])
    sysinfo = {}
    sysinfo['SYSTEM'] = {}
    
    try:
        sysinfo['SYSTEM']['SERIALPORT'] = config.get('serial', 'port')
    except (configparser.NoOptionError, configparser.InterpolationMissingOptionError):
        msg = ('No serial port specified in configuration file. Defaulting to /dev/ttyUSB0')
        sendlog(gotthefunc, msg, 40)
        sysinfo['SYSTEM']['SERIALPORT'] = '/dev/ttyUSB0'
        pass
    except configparser.Error as e:
        msg = ('Config read entry system serial port error! Halting!')
        sendlog(gotthefunc, msg, 40)
        sys.exit()
    except:
        msg = ('Error in {0} Reading Config! Halting!'.format(gotthefunc))
        sendlog(gotthefunc, msg, 40)
        err = traceback.format_exc()
        msg = ('Error Detail: {0}'.format(err))
        sendlog(gotthefunc, msg, 10)
        sys.exit()
        
    results = DisplayWorker(sysinfo, outputargs)
    sortedresults = collections.OrderedDict(sorted(results.items()))
    for key,val in sortedresults.items():
        if outputargs['debugoutput'] == 1:
            print("{0} = {1}".format(key,val))
        else:
            print("{}".format(val))
    if outputargs['debugoutput'] == 1:
        print('Took {}'.format(time() - tsmain))

if __name__ == '__main__':
   main()