# Verizon_Home_Limit
# -*- 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']")
    
    # ... (proceed directly into the Try/Catch block with the ActionChains logic)
    # # --- NEW STEP: EXPLICITLY LAUNCH THE APP ---
    print(f"Launching {APP_PACKAGE} to ensure a fresh session...")
    driver.activate_app(APP_PACKAGE)
    
    # # Give the app a few seconds to render the dashboard before we start hunting for elements
    time.sleep(5) 

    # # --- UI Locators ---
    # # Targets 'Network' specifically within a bottom navigation bar layout to avoid header elements
    # network_bottom_tab = (By.XPATH, "//*[contains(@resource-id, 'bottom') or contains(@resource-id, 'nav')]//*[@text='Network'] | //android.widget.FrameLayout[@content-desc='Network']")
    
    # Generic locator for the Android switch widget on the Guest page
    guest_switch_locator = (By.CLASS_NAME, "android.widget.Switch")

    try:
        # 1. Wait for Dashboard to settle
        print("Waiting for Dashboard to fully initialize...")
        time.sleep(3) # Generous buffer for backend UI rendering
        
        # 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
        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 == "true":
            print("Guest Wi-Fi is ON. Initiating shutdown sequence...")
            switch_element.click()
            
            print("Command sent. Waiting for backend processing to complete...")
            raise Exception("Simulated error after clicking the switch to verify if there is another step needed to confirm the toggle. This is intentional to test error handling and diagnostics.")
            # Custom wait: Polls the UI tree until the switch attribute permanently updates to "false"
            WebDriverWait(driver, 45).until(
                lambda d: d.find_element(*guest_switch_locator).get_attribute("checked") == "false"
            )
            print("Processing complete. Switch verified in the OFF position.")
            time.sleep(2)
        else:
            print("Guest Wi-Fi is already OFF. 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 Automation 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()