#!/usr/bin/env python
# Copyright (c) 2009-2015, Dwight Hubbard
# Copyrights licensed under the New BSD License
# See the accompanying LICENSE.txt file for terms.

"""
###############################################################
Digital Loggers Web Power Switch management
###############################################################
 Description: This is both a module and a script

              The module provides a python class named
              PowerSwitch that allows managing the web power
              switch from python programs.

              When run as a script this acts as a command
              line utility to manage the DLI Power switch.

              This module has been tested against the following 
              Digital Loggers Power network power switches:
                WebPowerSwitch II
                WebPowerSwitch III
                WebPowerSwitch IV
                WebPowerSwitch V
                Ethernet Power Controller III
"""
from __future__ import print_function
import sys
import optparse
from dlipower import PowerSwitch
from dlipower import DLIPowerException


def _block_to_list(block):
    """ Convert a range block into a numeric list
        input "1-3,17,19-20"
        output=[1,2,3,17,19,20]
    """
    block += ','
    result = []
    val = ''
    in_range = False
    for letter in block:
        if letter in [',', '-']:
            if in_range:
                val2 = val
                val2_len = len(val2)
                # result += range(int(val1),int(val2)+1)
                for value in outlet_range(int(val1), int(val2) + 1):
                    result.append(str(value).zfill(val2_len))
                val = ''
                val1 = None
                in_range = False
            else:
                val1 = val
                val1_len = len(val1)
                val = ''
            if letter == ',':
                if val1 != None:
                    result.append(val1.zfill(val1_len))
            else:
                in_range = True
        else:
            val += letter
    return result


def __command_on_outlets(action, outlet_range):
    """ Execute given action on switch with range argument.
        Handle exceptions.
    """
    try:
        return switch.command_on_outlets(action, outlet_range)
    except DLIPowerException as e:
        if not options.quiet:
            print(e, file=sys.stderr)
        sys.exit(1)
 

if __name__ == "__main__":
    usage = "usage: %prog [options] [status|on|off|cycle|get_outlet_name|set_outlet_name] [range|arg]"
    parser = optparse.OptionParser(usage=usage)
    parser.add_option('--hostname', dest='hostname', default=None,
                      help="hostname/ip of the power switch (default %default)")
    parser.add_option(
        '--timeout', dest='timeout', default=None,
        help="Timeout for value for power switch communication (default %default)"
    )
    parser.add_option(
        '--cycletime', dest='cycletime', default=None, type=int,
        help="Delay betwween off/on states for power cycle operations (default %default)"
    )
    parser.add_option('--user', dest='user', default=None,
                      help="userid to connect with (default %default)")
    parser.add_option('--password', dest='password', default=None,
                      help="password (default %default)")
    parser.add_option('--save_settings', dest='save_settings', default=False,
                      action='store_true',
                      help='Save the settings to the configuration file')
    parser.add_option(
        "--quiet", dest="quiet", default=False,
        action="store_true",
        help="Be quiet, don't print error messages only return error return codes (default False)"
    )
    (options, args) = parser.parse_args()

    switch = PowerSwitch(
        userid=options.user, password=options.password,
        hostname=options.hostname, timeout=options.timeout,
        cycletime=options.cycletime
    )
    if options.save_settings:
        switch.save_configuration()
    if len(args):
        operation = args[0].lower()
        outlet_range = _block_to_list(','.join(args[1:]))
        if len(args) > 1:
            if operation in ['status']:
                print(','.join(__command_on_outlets('status', outlet_range)))
            elif operation in ['on', 'poweron']:
                rc = __command_on_outlets('on', outlet_range)
                if rc and not options.quiet:
                    print("Power on operation failed", file=sys.stderr)
                sys.exit(rc)
            elif operation in ['off', 'poweroff']:
                rc = __command_on_outlets('off', outlet_range)
                if rc and not options.quiet:
                    print("Power off operation failed", file=sys.stderr)
            elif operation in ['cycle']:
                sys.exit(__command_on_outlets('cycle', outlet_range))
            elif operation in ['get_name', 'getname', 'get_outlet_name',
                               'getoutletname']:
                print(','.join(
                    __command_on_outlets('get_outlet_name', outlet_range)))
            elif operation in ['set_name', 'setname', 'set_outlet_name',
                               'setoutletname']:
                sys.exit(switch.set_outlet_name(args[1], args[2]))
            else:
                print("Unknown argument %s" % args[0])
    else:
        switch.printstatus()
