#!/usr/bin/env python
"""MyrtDesk API control app"""
from argparse import ArgumentParser
from asyncio import run
from myrt_desk_api import discover, MyrtDesk

parser = ArgumentParser()
parser.add_argument('--debug', default=False, action='store_true',
    help='Increases the amount of information the script prints')
parser.add_argument('-d', '--host', default=None,  action='store_true',
    help='MyrtDesk host address')
subparsers = parser.add_subparsers(help='List of commands', dest="command")
subparsers.default = None
# A color command
color_parser = subparsers.add_parser(
    'color', help='Set backlight color')
color_parser.add_argument(
    'hex_color', action='store', help='Hexadecimal color value')
reboot_parser = subparsers.add_parser(
    'reboot', help='Reboot desk')
effect_parser = subparsers.add_parser(
    'effect', help='Set backlight effect')
effect_parser.add_argument(
    'effect', action='store', type=int, help='Effect index')
# A white command
white_parser = subparsers.add_parser(
    'white', help='Set backlight color')
white_parser.add_argument(
    'warmness', type=int, action='store', help='0-255 warmness level')
# A flash-backlight command
firmware_parser = subparsers.add_parser(
    'flash-backlight', help='Update desk\'s backlight firmware')
firmware_parser.add_argument(
    'path', action='store', help='The path to the Intel HEX formatted firmware to be installed')
# A flash-controller command
flash_controller_parser = subparsers.add_parser(
    'flash-controller', help='Update desk\'s controller firmware')
flash_controller_parser.add_argument(
    'path', action='store', help='The path to the firmware to be installed'
)
# A power commands
subparsers.add_parser(
    'on', help='Enables backlight')
subparsers.add_parser(
    'off', help='Disables backlight')

def _print_progress (iteration):
    prefix = ''
    total = 100
    suffix = ''
    decimals = 1
    length = 70
    fill = '█'
    end = "\r"
    percent = ("{0:." + str(decimals) + "f}").format(100 * (iteration / float(total)))
    filled_length = int(length * iteration // total)
    fill_bar = fill * filled_length + '-' * (length - filled_length)
    print(f'\r{prefix} |{fill_bar}| {percent}% {suffix}', end=end)
    if iteration == total:
        print()

def _hex_to_rgb(val):
    return tuple(int(val[i : i + 2], 16) for i in (0, 2, 4))

async def main():
    """App entrypoint"""
    args = parser.parse_args()
    host = ''
    if args.host is None:
        discovered_host = await discover()
        if discovered_host is not None:
            host = discovered_host
        else:
            raise Exception("MyrtDesk is not found. Add --host argument")
    else:
        host = args.host
    desk = MyrtDesk(host)
    if args.command is None:
        state = await desk.backlight.read_state()
        print(state)
    elif args.command == 'color':
        hex_color = args.hex_color
        if len(hex_color) == 7:
            hex_color = hex_color[1:]
        color = _hex_to_rgb(hex_color)
        await desk.backlight.set_color(color)
    elif args.command == 'white':
        if args.warmness > 255:
            raise Exception("Wrong byte value")
        await desk.backlight.set_white(args.warmness)
    elif args.command == 'reboot':
        await desk.system.reboot()
    elif args.command == 'effect':
        await desk.backlight.set_effect(args.effect)
    elif args.command == 'flash-backlight':
        print("Updating desk's backlight firmware...")
        with open(args.path, mode="rb") as file:
            contents = file.read()
            def report_progress(val: float):
                _print_progress(val)
            await desk.backlight.update_firmware(contents, report_progress)
    elif args.command == 'flash-controller':
        print("Updating desk's controller firmware...")
        with open(args.path, mode="rb") as file:
            contents = file.read()
            def report_progress(val: float):
                _print_progress(val)
            await desk.system.update_firmware(contents, report_progress)
    elif args.command == 'off':
        await desk.backlight.set_power(False)
    elif args.command == 'on':
        await desk.backlight.set_power(True)
if __name__ == '__main__':
    run(main())
