# Verizon_Home_Enable
# -*- coding: utf-8 -*-
import os
import subprocess
import time
import requests
import traceback
from appium import webdriver
from appium.options.android import UiAutomator2Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains

# ==========================================
# CONFIGURATION & PARAMETERS
# ==========================================
key = 'dreYWZN6BkiImePegTZ5et'  # Replace with your IFTTT webhook key
event = 'tbn_event'             # Replace with your IFTTT event name

TARGET_DEVICE = '127.0.0.1:55555' 
APP_PACKAGE = 'com.verizon.homeapp'

def send_ifttt_webhook(event, key, message):
    """Send a webhook message to IFTTT."""
    url = f'https://maker.ifttt.com/trigger/{event}/with/key/{key}'
    data = {'value1': message}
    try:
        requests.post(url, json=data, timeout=10)
        print(f"Webhook sent with message: {message}")
    except Exception as e:
        print(f"Failed to transmit webhook: {e}")
    return None

def pre_launch_wake_and_start():
    """Ensure the headless canvas is awake and force start the app via OS-level Intent."""
    print("Waking up virtual display canvas...")
    
    subprocess.run("killall scrcpy", shell=True, stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL)

    # ### Enable the comment block below if you want to see the live feed during execution.
    # print("Launching live visual feed via Scrcpy on RDP display :10...")
    # subprocess.Popen(
    #     "export DISPLAY=:10 && scrcpy -s 127.0.0.1:55555 -f --bit-rate=2M --max-fps=30", 
    #     shell=True, 
    #     stdout=subprocess.DEVNULL, 
    #     stderr=subprocess.DEVNULL
    # )
    # time.sleep(2) 

    try:
        subprocess.run(f"adb connect {TARGET_DEVICE}", shell=True, timeout=5, stdout=subprocess.DEVNULL)
        subprocess.run(f"adb -s {TARGET_DEVICE} shell svc power stayon true", shell=True, timeout=10)
        subprocess.run(f"adb -s {TARGET_DEVICE} shell wm dismiss-keyguard", shell=True, timeout=10)

        print("Launching Verizon Home via OS-level monkey intent...")
        # The monkey command bypasses Appium's activity resolution entirely
        subprocess.run(f"adb -s {TARGET_DEVICE} shell monkey -p {APP_PACKAGE} -c android.intent.category.LAUNCHER 1", shell=True, timeout=15, stdout=subprocess.DEVNULL)
        
        # Give the app time to cold-boot and render the dashboard before Appium hooks in
        time.sleep(5)

    except subprocess.TimeoutExpired:
        print("CRITICAL: ADB command timed out! The Android network bridge is frozen.")
    time.sleep(2)

def force_close_app():
    """Force stops the Android app and spins down the headless session."""
    print("Force-stopping application package execution layers cleanly...")
    subprocess.run(f"adb -s {TARGET_DEVICE} shell am force-stop {APP_PACKAGE}", shell=True)
    subprocess.run("killall scrcpy", shell=True, stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL)
    print("System optimization cleanup complete. Session closed.")

def start_appium_session():
    """Initialize the cloud Appium options object matching Redroid architecture."""
    options = UiAutomator2Options()
    options.platform_name = "Android"
    options.automation_name = "UiAutomator2"
    options.device_name = TARGET_DEVICE
    options.udid = TARGET_DEVICE 
    
    # --- DELETED app_package AND app_wait_activity HERE ---
    # By removing them, Appium will simply attach to whatever is currently
    # visible on the screen (which the monkey command just launched).
    
    options.no_reset = True
    options.ensure_webviews_have_pages = True
    options.set_capability("androidHome", "/usr/lib/android-sdk")

    driver = webdriver.Remote('http://127.0.0.1:4723', options=options)
    return driver

# ==========================================
# EXECUTION PIPELINE
# ==========================================
if __name__ == "__main__":
    pre_launch_wake_and_start()
    driver = start_appium_session()
    print("Appium session established successfully.")

    # --- UI Locators ---
    network_text_locator = (By.XPATH, "//android.widget.TextView[@text='Network']")
    wifi_management_btn = (By.XPATH, "//*[@text='Wi-Fi Management' or contains(@text, 'Wi-Fi Management')]")
    guest_network_btn = (By.XPATH, "//*[@text='Guest']")
    
            print("No Service Update modal detected. Proceeding...")
        # -----------------------------------------------------------
        
        # Look specifically for the text element, completely ignoring layout wrappers
        network_text_locator = (By.XPATH, "//android.widget.TextView[@text='Network']")
        
        print("Attempting human-like tap on 'Network' tab...")
        
        # Use presence instead of clickable to ensure we just get the coordinates
        network_element = WebDriverWait(driver, 20).until(
            EC.presence_of_element_located(network_text_locator)
        )
        
        # Force a hardware-style pointer click instead of a DOM accessibility click
        actions = ActionChains(driver)
        actions.move_to_element(network_element).click().perform()
        print("Clicked 'Network'.")            
        time.sleep(2) # Give the UI transition a moment
            
        # 2. Navigate to Wi-Fi Management
        print("Looking for 'Wi-Fi Management'...")
        wifi_mgmt = WebDriverWait(driver, 15).until(
            EC.element_to_be_clickable(wifi_management_btn)
        )

        # Force a hardware-style pointer click instead of a DOM accessibility click
        actions2 = ActionChains(driver)
        actions2.move_to_element(wifi_mgmt).click().perform()
        print("Clicked 'Wi-Fi Management'.")
        time.sleep(2)

        # 3. Enter Guest Network Settings
        print("Looking for 'Guest' network option...")
        guest_nav = WebDriverWait(driver, 15).until(
            EC.element_to_be_clickable(guest_network_btn)
        )
        actions3 = ActionChains(driver)
        actions3.move_to_element(guest_nav).click().perform()
        print("Entered 'Guest' network page.")
        time.sleep(2)

        # 4. Evaluate and Toggle the Switch (Turning ON)
        print("Evaluating current Guest Wi-Fi state...")
        switch_element = WebDriverWait(driver, 15).until(
            EC.presence_of_element_located(guest_switch_locator)
        )
        
        is_checked = switch_element.get_attribute("checked")
        
        if is_checked == "false":
            print("Guest Wi-Fi is OFF. Initiating startup sequence...")
            
            # Use ActionChains to ensure the hardware click registers exactly on the toggle
            actions_switch = ActionChains(driver)
            actions_switch.move_to_element(switch_element).click().perform()
            
            print("Toggle clicked. Looking for confirmation modal...")
            
            # --- Handle the Confirmation Modal for Turning ON ---
            try:
                # Target the clickable text anywhere on the screen
                confirm_on_locator = (By.XPATH, "//*[contains(@text, 'Turn on Wi-Fi') or contains(@text, 'Turn on')]")
                
                # Wait up to 5 seconds for the modal to pop up
                confirm_btn = WebDriverWait(driver, 5).until(
                    EC.element_to_be_clickable(confirm_on_locator)
                )
                
                # Perform a hardware-style tap on the confirmation text
                actions_confirm = ActionChains(driver)
                actions_confirm.move_to_element(confirm_btn).click().perform()
                print("Confirmed 'Turn on Wi-Fi' on the modal.")
                
                time.sleep(2) # Give the modal time to dismiss visually
            except Exception:
                # If the modal doesn't appear within 5 seconds, it simply moves on
                print("No confirmation modal detected or it was bypassed. Proceeding...")
            # -----------------------------------------------
            
            print("Command sent. Waiting for backend processing to complete...")
            print("Note: The Verizon UI indicates this can take up to 1 minute.")
            
            # Custom wait function: Silently handles missing elements while the loading screen is active
            def verify_switch_on(d):
                try:
                    return d.find_element(*guest_switch_locator).get_attribute("checked") == "true"
                except Exception:
                    # If the switch is missing because the spinner is up, return False and keep waiting
                    return False

            # Bumped the timeout to 85 seconds to safely clear the 1-minute loading timer
            WebDriverWait(driver, 85).until(verify_switch_on)
            
            print("Processing complete. Switch verified in the ON position.")
            time.sleep(2)
            
        else:
            print("Guest Wi-Fi is already ON. No action required.")

    except Exception as e:
        print("\n=======================================================")
        print(f"❌ CRITICAL FAULT TRIPPED: {e}")
        print("=======================================================")
        
        traceback.print_exc() 
        send_ifttt_webhook(event, key, "Verizon Guest Wi-Fi Enable Failed!")

        try:
            print("\nSnapping emergency triage screenshots and layout XML...")
            driver.save_screenshot('/home/ubuntu/verizon_home_fault.png')
            with open('/home/ubuntu/verizon_home_layout.xml', 'w', encoding='utf-8') as f:
                f.write(driver.page_source)
            print("✅ Diagnostics saved to /home/ubuntu/verizon_home_fault.png and /home/ubuntu/verizon_home_layout.xml")
            
            print("\n🚨 EXECUTION PAUSED FOR DEBUGGING 🚨")
            print("1. Look at your scrcpy window to see where the app is stuck.")
            print("2. Open the layout XML to inspect the current UI tree if a locator failed.")
            input("\n👉 Press [ENTER] in this terminal when you are ready to kill the app and exit...")

        except Exception as diag_err:
            print(f"Failed to capture diagnostics: {diag_err}")

    finally:
        print("Safely disconnecting client driver stream links...")
        try:
            driver.quit()
        except:
            pass
        
        force_close_app()