import subprocess
import time
import requests
from appium import webdriver
from appium.options.android import UiAutomator2Options
from selenium.webdriver.common.by import By
from appium.webdriver.common.appiumby import AppiumBy

# ==========================================
# CONFIGURATION & PARAMETERS
# ==========================================
Password_Here = "G@Udn1w@#8N8"
key = 'dreYWZN6BkiImePegTZ5et'  # Replace with your IFTTT webhook key
event = 'tbn_event'          # Replace with your IFTTT event name

feed_caramelo = True
perform_plus_caramelo = False
perform_confirm_caramelo = False

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 with foreground priority."""
    print("Waking up virtual display canvas...")
    subprocess.run("adb shell svc power stayon true", shell=True)
    subprocess.run("adb shell wm dismiss-keyguard", shell=True)

    print("Launching Petlibro via Activity Manager...")
    # Using the verified working foreground-accelerated execution call
    subprocess.run("adb shell am start -W -n com.designlibro.petlibro/.MainActivity --receiver-foreground -f 0x10000000", shell=True)
    time.sleep(5)

def start_appium_session():
    """Initialize the cloud Appium options object matching Waydroid architecture."""
    options = UiAutomator2Options()
    options.platform_name = "Android"
    options.automation_name = "UiAutomator2"
    options.device_name = "192.168.240.2:5555"
    options.udid = "192.168.240.2:5555"
    options.app_package = "com.designlibro.petlibro"
    options.app_activity = ".MainActivity"
    options.no_reset = True
    options.ensure_webviews_have_pages = True

    # Inject the missing Android SDK paths directly into the session capabilities
    options.set_capability("androidHome", "/usr/lib/android-sdk")

    # Creates a dual-tunnel for both the Petlibro API and the Kalay IoT hardware backend
    #options.set_capability("androidHostsMapping", "api.us.petlibro.com 98.94.221.157, mdk-im.kalay.net.cn 47.96.78.87")

    # Connecting directly to the local Appium server daemon endpoint on the host
    driver = webdriver.Remote('http://127.0.0.1:4723', options=options)
    return driver

# Pre-wake display canvas and force app execution
pre_launch_wake_and_start()

# Start the Appium UI automation driver session
driver = start_appium_session()
print("Appium session established successfully.")

# ==========================================
# LOCATORS (Maintained from your verified set)
# ==========================================
caramelo_locator = (By.XPATH, "//android.widget.Button[@content-desc='Kitchen\nCaramelo Bona\nNext feeding:\nNo Feeding Schedule ']")
feed_now_locator = (By.XPATH, "//android.widget.ImageView[@content-desc='Feed Now']")
plus_locator = (By.XPATH, "//android.view.View[@content-desc='10 g']/android.widget.ImageView[2]") 
confirm_locator = (AppiumBy.ACCESSIBILITY_ID, "Confirm")
back_locator = (By.XPATH, "//android.widget.FrameLayout[@resource-id='android:id/content']/android.widget.FrameLayout/android.widget.FrameLayout/android.view.View/android.view.View/android.view.View/android.view.View/android.widget.ImageView[1]")

# Login and popup mitigation locators
agree_continue_locator = (By.XPATH, "//*[@text='Agree And Continue' or @content-desc='Agree And Continue']")
again_locator = (By.XPATH, "//android.widget.Button[@content-desc='ACCOUNT LOGIN HAS EXPIRED. PLEASE LOG IN AGAIN\nOK']")
password_locator = (By.XPATH, "//android.widget.FrameLayout[@resource-id='android:id/content']/android.widget.FrameLayout/android.widget.FrameLayout/android.view.View/android.view.View/android.view.View/android.view.View/android.view.View/android.view.View/android.view.View/android.widget.EditText[2]")
checkbox_locator = (By.XPATH, "//android.widget.FrameLayout[@resource-id='android:id/content']/android.widget.FrameLayout/android.widget.FrameLayout/android.view.View/android.view.View/android.view.View/android.view.View/android.view.View/android.view.View/android.view.View/android.widget.ImageView[2]")
login_locator = (By.XPATH, "//android.widget.Button[@content-desc='Log In']")
quit_market_message = (By.XPATH, "//android.widget.FrameLayout[@resource-id='android:id/content']/android.widget.FrameLayout/android.widget.FrameLayout/android.view.View/android.view.View/android.view.View[1]/android.view.View/android.view.View/android.view.View/android.view.View/android.widget.ImageView[2]")

try:

    # 1. Handle "Agree and Continue" policy block if rendering on clean canvas
    try:
        agree_btn = driver.find_elements(*agree_continue_locator)
        if agree_btn:
            agree_btn[0].click()
            print("Terms and Conditions prompt detected and handled successfully.")
            time.sleep(3)
    except Exception as e:
        print(f"Skipping Terms step: {e}")

    # --- NEW SYSTEM NOTIFICATION BYPASS LAYER ---
    time.sleep(5)
    try:
        print("Checking for native Android system notification permission prompt...")
        # Using an explicit 5-second wait so it doesn't stall if the prompt doesn't show
        from selenium.webdriver.support.ui import WebDriverWait
        from selenium.webdriver.support import expected_conditions as EC
        from selenium.webdriver.common.by import By

        deny_button = WebDriverWait(driver, 5).until(
            EC.presence_of_element_located((By.ID, "com.android.permissioncontroller:id/permission_deny_button"))
            )
        deny_button.click()
        print("Handled notification prompt: Clicked 'Don't allow'.")
    except Exception:
        print("No notification permission prompt detected or it was already dismissed. Moving on...")

    for attempt in range(1, 1):
            try:
                print(f"Checking for native system permission prompt (Attempt {attempt}/3)...")
                from selenium.webdriver.support.ui import WebDriverWait
                from selenium.webdriver.support import expected_conditions as EC
                from selenium.webdriver.common.by import By

                # Look for the 'Don't allow' resource ID
                deny_button = WebDriverWait(driver, 4).until(
                    EC.element_to_be_clickable((By.XPATH, "//*[@text='Don’t allow' or @text=\"Don't allow\"]"))
                )
                deny_button.click()
                print("Handled notification prompt successfully: Clicked 'Don't allow'.")
                break
            except Exception:
                print("Prompt not detected on this attempt. Sleeping 2 seconds...")
                time.sleep(2)

    # 2. Handle login expiration popups
    try:
        if driver.find_elements(*again_locator):
            driver.find_element(*again_locator).click()
            time.sleep(2)
            driver.tap([(640, 780)]) # Adjusted tap vector coordinate sequence to target typical center elements
            time.sleep(2)
    except:
        print("No login expiration popup found, proceeding...")

    # 3. Check for structural login screen fields
    try:
        login_elements = driver.find_elements(*login_locator)
        if login_elements:
            login_elements[0].click()
            time.sleep(2)

    except Exception as e:
        print(f"Login routine skipped or encountered verification exception: {e}")

    # --- FLUTTER-ADAPTIVE LOGIN ROUTINE ---
    try:
        print("Waiting for Flutter UI view layers to stabilize...")
        from selenium.webdriver.support.ui import WebDriverWait
        from selenium.webdriver.support import expected_conditions as EC
        from selenium.webdriver.common.by import By
        import time

        # 1. Target the Email input field by checking text or content-desc properties on generic views
        print("Locating Email field...")
        email_field = WebDriverWait(driver, 15).until(
            EC.element_to_be_clickable((By.XPATH, "//*[@class='android.view.View' and (@text='Email' or contains(@content-desc, 'Email'))] | //android.widget.EditText"))
            )
        email_field.click()
        time.sleep(0.3)
        email_field.send_keys("alexandre.bona@gmail.com")
        print("Email field populated.")

        # 2. Target the Password input field
        print("Locating Password field...")
        password_field = driver.find_element(By.XPATH, "//*[@class='android.view.View' and (@text='Password' or contains(@content-desc, 'Password'))] | //android.widget.EditText[2]")
        password_field.click()
        time.sleep(0.3)
        password_field.send_keys(Password_Here)
        print("Password field populated.")
        driver.press_keycode(66)
        time.sleep(0.3)

        # 3. Handle the terms checkbox (Direct Attribute Target)
        try:
            print("Targeting checkbox directly via index and clickable properties...")

            # Method 1: Target by its exact index and clickable state
            checkbox = WebDriverWait(driver, 10).until(
                EC.element_to_be_clickable((By.XPATH, "//android.widget.ImageView[@index='5' and @clickable='true']"))
            )
            checkbox.click()
            print("Checkbox matched and clicked successfully!")
            time.sleep(0.3)

        except Exception as primary_err:
            print(f"Index locator failed: {primary_err}")
        # 4. Click the primary, clickable Log In Button (Filtered by index & state)
        print("Locating the specific clickable Log In button layer...")

        # Locks directly onto the exact index="7" button matching your layout dump
        login_button = WebDriverWait(driver, 10).until(
            EC.element_to_be_clickable((By.XPATH, "//android.widget.Button[@index='7' and @content-desc='Log In' and @clickable='true']"))
        )
        login_button.click()
        print("Log In button clicked successfully! Session authentication transmitted.")

        # Give the dashboard a solid moment to load after form submission
        time.sleep(0.3)

    except Exception as login_err:
        print(f"Login routine encountered an exception. The app is probably logged in already.")

    # ----------------------------------------------------
    # 5. POST-LOGIN INTERCEPT GAUNTLET
    # ----------------------------------------------------
    from appium.webdriver.common.appiumby import AppiumBy

    print("Session authenticated! Waiting 8 seconds for Kalay cloud sync...")
    time.sleep(8) 
    
    # --- INTERCEPT 1: THE MESSAGE CENTER ---
    print("Checking for Message Center hijack...")
    try:
        WebDriverWait(driver, 5).until(
            EC.presence_of_element_located((AppiumBy.XPATH, "//android.view.View[@content-desc='MESSAGE CENTER']"))
        )
        print("Trapped in Message Center! Clicking the back arrow...")
        back_arrow = driver.find_element(AppiumBy.XPATH, "//android.widget.ImageView[@index='0' and @clickable='true']")
        back_arrow.click()
        time.sleep(4) # Give the dashboard time to render after clicking back
    except Exception:
        print("No Message Center intercepted.")

    # --- INTERCEPT 2: THE "DONE" TOOLTIP ---
    # This MUST happen after the Message Center check, because escaping the 
    # Message Center is what triggers this tooltip to spawn!
    print("Checking for the First-Time 'Done' tooltip on the dashboard...")
    try:
        # 1. Try standard Accessibility ID click
        target = WebDriverWait(driver, 5).until(
            EC.presence_of_element_located((AppiumBy.ACCESSIBILITY_ID, "Done"))
        )
        print("Tooltip detected! Firing native click...")
        target.click()
        time.sleep(3)
    except Exception:
        try:
            # 2. If Flutter blocks it, fallback to dynamic UIAutomator pixel scaling
            print("Fallback: Attempting UIAutomator clickGesture...")
            target = driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR, 'new UiSelector().descriptionContains("Done")')
            driver.execute_script("mobile: clickGesture", {"elementId": target.id})
            time.sleep(3)
        except Exception:
            print("No 'Done' tooltip detected. Dashboard is completely clear.")

    # 5. Core Pet Feeding Pipeline Target Execution Loop
    if feed_caramelo:
        print("Locating Caramelo's machine entry profile...")
        driver.find_element(*caramelo_locator).click()
        time.sleep(2)

        print("Triggering instant feed canvas overlay...")
        driver.find_element(*feed_now_locator).click()
        time.sleep(2)
        if perform_plus_caramelo:
            print("Incrementing weight portion size (+10g)...")
            driver.find_element(*plus_locator).click()
            time.sleep(2)

        if not perform_confirm_caramelo:
            print("Aborting feeding action loop: issuing back keycode.")
            driver.press_keycode(4)
            time.sleep(2)

        if perform_confirm_caramelo:
            print("Feeding validation confirmed. Delivering treats immediately.")
            driver.find_element(*confirm_locator).click()
            time.sleep(2)

        print("Returning interface map to root layer...")
        driver.find_element(*back_locator).click()
        time.sleep(2)

except Exception as e:
        print(f"Critical execution block fault tripped: {e}")
        send_ifttt_webhook(event, key, "Feed Failed!")

        # --- NEW DIAGNOSTIC LAYER ---
        try:
            print("Snapping emergency triage screenshots and layout XML...")
            # Save a screenshot to your home directory
            driver.save_screenshot('/home/ubuntu/caramelo_fault.png')

            # Save the raw UI layout to see the exact text/resource IDs
            with open('/home/ubuntu/caramelo_layout.xml', 'w', encoding='utf-8') as f:
                f.write(driver.page_source)

            print("Diagnostics saved to ~/caramelo_fault.png and ~/caramelo_layout.xml")

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

        # Your existing webhook and cleanup steps continue below
        # Webhook sent with message: Feed Failed!...

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

    print("Force-stopping application package execution layers cleanly...")
    # Hard teardown step ensures container system background memory stays clean
    subprocess.run("adb shell am force-stop com.designlibro.petlibro", shell=True)
    print("System optimization cleanup complete. Session closed.")
