#!/usr/bin/python3
# vim:expandtab:autoindent:tabstop=4:shiftwidth=4:filetype=python:tw=0

  #############################################################################
  #
  # Copyright (c) 2005 Dell Computer Corporation
  # Dual Licenced under GNU GPL and OSL
  #
  #############################################################################
"""smbios-wakeup-ctl"""




# import arranged alphabetically
import gettext
import locale
import os
import struct
import sys
import traceback

# the following vars are all substituted on install
# this bin isnt byte-compiled, so this is ok
pythondir="/usr/lib/python3.13/site-packages"
clidir="/usr/share/smbios-utils"
# end vars

# import all local modules after this.
sys.path.insert(0,pythondir)
sys.path.insert(0,clidir)

import cli
from libsmbios_c import smbios_token, localedir, GETTEXT_PACKAGE
from libsmbios_c.trace_decorator import traceLog, getLog
from libsmbios_c import system_info as sysinfo

__VERSION__="2.4.3"

locale.setlocale(locale.LC_ALL, '')
gettext.install(GETTEXT_PACKAGE, localedir)

moduleLog = getLog()
verboseLog = getLog(prefix="verbose.")

token_wake_hour = 0x2b
token_wake_min = 0x2c
token_wake_disable = 0x28
token_wake_everyday = 0x29
token_wake_weekday = 0x2a

class CmdlineError(Exception): pass

def command_parse():
    parser = cli.OptionParser(usage=__doc__, version=__VERSION__)
    parser.add_option('--hour', action="store", dest="hour", default=0, help= _("Set wakeup hour. Must be 0-23"), )
    parser.add_option('--minute', action="store", dest="minute", default=0, help= _("Set wakeup minute. Must be 0-59"), )
    parser.add_option('--everyday', action="store_const", const=token_wake_everyday, dest="action", default=None, help= _("Set wakeup for every day"), )
    parser.add_option('--weekday', action="store_const", const=token_wake_weekday, dest="action",  help= _("Set wakeup for weekdays only"), )
    parser.add_option('--disable', action="store_const", const=token_wake_disable, dest="action", help= _("Disable wakeups"), )
    cli.addStdOptions(parser)
    return parser.parse_args()

def xform_options(options):
    options.hour = int(options.hour)
    if options.hour < 0 or options.hour > 23:
        raise Exception( _("Wakeup hour must be between 0 and 23. You passed: '%s'") % options.hour)

    options.minute = int(options.minute)
    if options.minute < 0 or options.minute > 59:
        raise Exception( _("Wakeup min must be between 0 and 59. You passed: '%s'") % options.minute)

    options.hour_bcd = ((options.hour // 10) <<4) + (options.hour % 10)
    options.min_bcd = ((options.minute // 10) <<4) + (options.minute % 10)

def getWakeupTime(table):
    hour = struct.unpack("b", table[token_wake_hour].getString()[0])
    minute = struct.unpack("b", table[token_wake_min].getString()[0])
    # time is BCD coded
    return ( int("%x" % hour), int("%x"%minute) )

def showCurrentWakeup(table):
    if table[token_wake_disable].isActive():
        print(_("\tWakeup disabled"))
    if table[token_wake_everyday].isActive():
        print(_("\tWakeup every day"))
        print(_("\tWakeup time:  %02d:%02d") % getWakeupTime(table))
    if table[token_wake_weekday].isActive():
        print(_("\tWakeup weekdays"))
        print(_("\tWakeup time:  %02d:%02d") % getWakeupTime(table))


def main():
    exit_code = 0
    (options, args) = command_parse()
    cli.setup_std_options(options)
    xform_options(options)

    try:
        table = smbios_token.TokenTable()

        print(_("Current wakeup settings:"))
        showCurrentWakeup(table)

        if options.action:
            print()
            print(_("Setting new wakeup time:"))
            table[options.action].tryPassword(options.password_ascii, options.password_scancode)
            table[options.action].activate()
            table[token_wake_hour].tryPassword(options.password_ascii, options.password_scancode)
            table[token_wake_hour].setString(struct.pack("b", options.hour_bcd))
            table[token_wake_min].tryPassword(options.password_ascii, options.password_scancode)
            table[token_wake_min].setString(struct.pack("b", options.min_bcd))
            showCurrentWakeup(table)

    except (IndexError, ) as e:
        exit_code=10
        moduleLog.info( _("ERROR: This system does not support programmed wakeups.") )

    except (smbios_token.TokenTableParseError, ) as e:
        exit_code=3
        moduleLog.info( _("ERROR: Could not parse system SMBIOS table.") )
        verboseLog.info( _("The smbios library returned this error:") )
        verboseLog.info( str(e) )
        moduleLog.info( cli.standardFailMessage )

    except (smbios_token.TokenManipulationFailure,) as e:
        exit_code=4
        moduleLog.info( _("ERROR: Could not manipulate system token.") )
        verboseLog.info( _("The token library returned this error:") )
        verboseLog.info( str(e) )
        moduleLog.info( cli.standardFailMessage )

    return exit_code

if __name__ == "__main__":
    sys.exit( main() )

