#!/usr/bin/python -tt
from __future__ import with_statement
import optparse
import sys
import os
import struct

import iguanaIR

#output "constants"
LOG_FATAL  = 0
LOG_ERROR  = 1
LOG_WARN   = 2
LOG_ALWAYS = 2.5
LOG_NORMAL = 3
LOG_INFO   = 4
LOG_DEBUG  = 5

msgPrefixes = [
    "FATAL: ",
    "ERROR: ",
    "WARNING: ",
    "",
    "INFO: ",
    "DEBUG: "
]

#local variables
null = open(os.devnull, 'r+')
parser = optparse.OptionParser()
options = None

def dieCleanly(level = None):
    """Exit the application with proper cleanup."""

    #TODO: perform application cleanup

    if level == None:
        level = LOG_ERROR

    #exit with appropriate value
    if level == LOG_FATAL:
        sys.exit(1)
    sys.exit(0)


def message(level, msg):
    global options
    """Print a message to a certain debug level"""
    retval = None

    if level <= options.logLevel or level == LOG_ALWAYS:
        out = sys.stdout

        # if logfile is open print to it instead
        if options.logFile == "-":
            out = sys.log
        elif level <= LOG_WARN:
            out = sys.stderr

        retval = msgPrefixes[int(level + 0.5)] + msg
        out.write(retval)
        retval = len(retval)

    if level <= LOG_FATAL:
        dieCleanly(level)

    return retval

def printUsage(msg = None):
    global parser
    if msg != None:
        message(LOG_FATAL, msg + parser.get_usage())
    message(LOG_ALWAYS, usage)
    dieCleanly(LOG_ALWAYS)

def parseOptions():
    global parser, options
    parser.add_option('-l', '--log-file',
                      metavar = 'FILE', dest = 'logFile',
                      help = 'Specify a log to receive all messages.')
    parser.add_option('-d', '--device',
                      metavar = 'ID', default = '0',
                      help = 'Which device do you want to connect to?')
    parser.add_option('--id',
                      metavar = 'ID', default = '',
                      help = 'New id for the device.')
    parser.add_option('-q', '--quiet',
                      action = 'count',
                      help = 'Decrease verbosity.')
    parser.add_option('-v', '--verbose',
                      action = 'count',
                      help = 'Increase verbosity.')
    (options, leftover) = parser.parse_args()
    options.logLevel = LOG_NORMAL;
    if options.verbose:
        options.logLevel += options.verbose
    if options.quiet:
        options.logLevel -= options.quiet
        if options.logLevel <= LOG_FATAL:
            options.logLevel = LOG_FATAL
    if options.logFile == '-':
        options.logFile = None
    if leftover:
        printUsage("Unknown argument: " + leftover[0] + "\n")

def deviceTransaction(id, data = ''):
    global conn

    req = iguanaIR.createRequest(id, data)
    if not iguanaIR.writeRequest(req, conn):
        message(LOG_FATAL, 'Failed to disable IDs in the daemon.\n')
    resp = iguanaIR.readResponse(conn, 1000)
    if resp is None or \
       iguanaIR.responseIsError(resp):
        message(LOG_FATAL, 'Error response received from the daemon.\n')

parseOptions()
# open the log file if specified
if options.logFile != None:
    sys.log = open(options.logFile, "a", 1)
    options.logFile = "-"

conn = iguanaIR.connect(options.device)
if conn == -1:
    message(LOG_FATAL, 'Failed to connect to the daemon/device.\n')

deviceTransaction(iguanaIR.IG_DEV_IDSOFF)
if options.id is not None:
    temp = ''
    for char in options.id + chr(0):
        temp += struct.pack('B', ord(char))
    options.id = temp
deviceTransaction(iguanaIR.IG_DEV_SETID, options.id)
deviceTransaction(iguanaIR.IG_DEV_IDSON)

page = {
    'start'  : 0x1fc0,
    'bytes'  : ['0x30'] * 64,
    'data'   : '',
    'chksum' : 0
}

chksum = 0
for x in page['bytes']:
    chksum += int(x, 16)
page['chksum'] = chksum

# construct 68 data bytes we need
page['data'] = chr(page['start'] / 64)
page['data'] += chr(0)
page['data'] += chr(page['chksum'] / 0x100) + \
                chr(page['chksum'] % 0x100)
for byte in page['bytes']:
    page['data'] += chr(int(byte, 16))

print page 

deviceTransaction(iguanaIR.IG_DEV_WRITEBLOCK, page['data'])
