"""µDucky - DuckyScript™ in CircuitPython

Setup

    1. Flash the CircuitPython firmware
    2. Install the adafruid_hid library
    3. mv uducky.py main.py
    4. ed payload.txt
    5. echo 'import storage; storage.disable_usb_drive()' > boot.py
"""

import time
import supervisor
import board
import digitalio
import usb_hid
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keycode import Keycode
from adafruit_hid.keyboard_layout_us import KeyboardLayout

supervisor.runtime.autoreload = False
led = digitalio.DigitalInOut(board.LED)
led.switch_to_output()
keyboard = Keyboard(usb_hid.devices)
layout = KeyboardLayout(keyboard)
default_delay = 1  # in seconds

time.sleep(3)

with open("payload.txt") as f:
    for line in f:
        commands = line.upper().split()
        if not len(commands) or commands[0] == "REM":
            continue
        elif commands[0] == "DEFAULTDELAY":
            default_delay = float(commands[1]) / 1000
        elif commands[0] == "DELAY":
            time.sleep(float(commands[1]) / 1000)
        elif commands[0] == "STRING":
            layout.write(line[7:])
        elif commands[0][:3] == "LED":
            led.value = not led.value
        else:
            keys = []
            for command in commands:
                if command[:2] == "UP":
                    keys.append(Keycode.UP_ARROW)
                elif command[:4] == "DOWN":
                    keys.append(Keycode.DOWN_ARROW)
                elif command[:4] == "LEFT":
                    keys.append(Keycode.LEFT_ARROW)
                elif command[:5] == "RIGHT":
                    keys.append(Keycode.RIGHT_ARROW)
                elif command == "PAGEUP":
                    keys.append(Keycode.PAGE_UP)
                elif command == "PAGEDOWN":
                    keys.append(Keycode.PAGE_DOWN)
                elif command == "DEL":
                    keys.append(Keycode.DELETE)
                elif command == "ESC":
                    keys.append(Keycode.ESCAPE)
                elif command == "BREAK":
                    keys.append(Keycode.PAUSE)
                elif command == "PRINTSCREEN":
                    keys.append(Keycode.PRINT_SCREEN)
                elif command == "MENU" or command == "APP":
                    keys.append(Keycode.APPLICATION)
                elif command == "CTRL":
                    keys.append(Keycode.CONTROL)
                elif command == "CAPSLOCK":
                    keys.append(Keycode.CAPS_LOCK)
                elif command == "NUMLOCK":
                    keys.append(Keycode.KEYPAD_NUMLOCK)
                elif command == "SCROLLOCK":
                    keys.append(Keycode.SCROLL_LOCK)
                elif hasattr(Keycode, command):
                    keys.append(getattr(Keycode, command))
            keyboard.send(*keys)
        time.sleep(default_delay)
