import os
import time
import subprocess
from datetime import datetime

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


# =====================================================
# CONFIGURATION
# =====================================================

DEVICE_IP = "192.168.1.254"
DEVICE_URL = f"http://{DEVICE_IP}"

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))

FIRMWARE_FILE = os.path.join(
    SCRIPT_DIR,
    "firmware333.ubi"
)

LOG_FILE = os.path.join(SCRIPT_DIR, "flash_log.txt")


# =====================================================
# LOGGING
# =====================================================

def log(message):
    line = f"[{datetime.now()}] {message}"
    print(line)

    with open(LOG_FILE, "a", encoding="utf-8") as f:
        f.write(line + "\n")


# =====================================================
# DEVICE DETECTION
# =====================================================

def ping_device():
    result = subprocess.run(
        ["ping", "-n", "1", "-w", "1000", DEVICE_IP],
        stdout=subprocess.DEVNULL,
        stderr=subprocess.DEVNULL
    )
    return result.returncode == 0


def wait_for_device():
    log("Waiting for device network...")

    while True:
        if ping_device():
            log("Device detected.")
            return

        time.sleep(1)


def wait_until_device_goes_down():
    log("Waiting for device to reboot/disconnect...")

    while ping_device():
        time.sleep(1)

    log("Device went offline.")


# =====================================================
# FIRMWARE UPLOAD
# =====================================================

def upload_firmware():

    if not os.path.exists(FIRMWARE_FILE):
        raise FileNotFoundError(
            f"Firmware file not found:\n{FIRMWARE_FILE}"
        )

    options = webdriver.ChromeOptions()

    driver = webdriver.Chrome(options=options)

    wait = WebDriverWait(driver, 20)

    try:
        log("Opening firmware page...")

        driver.get(DEVICE_URL)

        file_input = wait.until(
            EC.presence_of_element_located((By.NAME, "firmware"))
        )

        file_input.send_keys(FIRMWARE_FILE)

        log("Firmware selected.")

        update_button = driver.find_element(
            By.CSS_SELECTOR,
            "input[type='submit']"
        )

        update_button.click()

        log("Firmware upload clicked.")

        # Give browser a few seconds to submit
        time.sleep(10)

    finally:
        driver.quit()


# =====================================================
# MAIN LOOP
# =====================================================

def main():

    count = 1

    log("Auto Firmware Flasher Started")

    while True:

        log("=" * 60)
        log(f"Ready for unit #{count}")

        wait_for_device()

        try:
            upload_firmware()

            log(
                f"Unit #{count}: firmware upload started successfully."
            )

        except Exception as e:

            log(
                f"Unit #{count}: ERROR: {str(e)}"
            )

        wait_until_device_goes_down()

        log(f"Unit #{count}: complete. Connect next device.")

        count += 1

        time.sleep(3)


# =====================================================
# ENTRY
# =====================================================

if __name__ == "__main__":
    main()