#!/usr/bin/env python3
"""
i21 Integration SQL execution via headless browser.
Login via curl (bypass reCAPTCHA), inject cookies into Playwright.
"""
import subprocess, re, json, asyncio, time
from playwright.async_api import async_playwright

IP = "66.175.238.112"
APP = "2610RTROGERSUAP1"
BASE = f"http://{IP}/{APP}"

def curl_login(ip, app):
    subprocess.run(["curl","-sS","-m","15","-c","/tmp/pl1.txt","-o","/tmp/pp1.html",
                    f"http://{ip}/{app}/login"], capture_output=True, text=True, timeout=20)
    page = open("/tmp/pp1.html").read()
    tm = re.search(r'name="__RequestVerificationToken"[^>]*value="([^"]*)"', page)
    if not tm: return None
    token = tm.group(1)
    r2 = subprocess.run(["curl","-sS","-m","15","-c","/tmp/pl2.txt","-o","/dev/null","-w","%{http_code}",
                         "-b","/tmp/pl1.txt","-X","POST",f"http://{ip}/{app}/login",
                         "-H","Content-Type: application/x-www-form-urlencoded",
                         "-d",f"__RequestVerificationToken={token}&Email=irelyadmin&Password=i21By2015&Company=01&RememberMe=false&Concurrency=&CompanyPrefConcurrency=&UserPrefConcurrency=&Debug=False&Hash="],
                        capture_output=True, text=True, timeout=20)
    if r2.stdout.strip() != "302": return None
    cookies = []
    with open("/tmp/pl2.txt") as f:
        for line in f:
            if line.strip() and not line.startswith("#") and "\t" in line:
                parts = line.strip().split("\t")
                if len(parts) >= 7:
                    cookies.append({
                        "name": parts[5], "value": parts[6],
                        "domain": parts[0].lstrip(".").replace("#HttpOnly_",""),
                        "path": parts[2], "httpOnly": "#HttpOnly" in parts[0]
                    })
    return cookies

async def main():
    print("=== Login via curl ===")
    cookies = curl_login(IP, APP)
    if not cookies:
        print("Login failed"); return
    print(f"Got {len(cookies)} cookies")

    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=True)
        context = await browser.new_context(viewport={"width":1920,"height":1080}, ignore_https_errors=True)
        
        for c in cookies:
            try:
                await context.add_cookies([{
                    "name": c["name"], "value": c["value"],
                    "url": f"http://{c['domain']}{c['path']}", "httpOnly": c.get("httpOnly",False)
                }])
            except: pass
        
        page = await context.new_page()
        
        ajax_logs = []
        def on_resp(resp):
            url = resp.url
            if "/api/" in url or "/Integration" in url or "Step" in url:
                ajax_logs.append({"m":resp.request.method,"u":url.split(APP)[-1][:80],"s":resp.status})
        page.on("response", on_resp)
        
        try:
            print("\n=== Dashboard ===")
            await page.goto(f"{BASE}/", wait_until="networkidle", timeout=30000)
            await asyncio.sleep(5)
            if "login" in page.url:
                print("  ❌ Redirected to login"); await browser.close(); return
            print(f"  ✅ Dashboard: {page.url}")
            await page.screenshot(path="/tmp/dash.png")
            
            # Navigate to Integration
            print("\n=== Integration module ===")
            await page.goto(f"{BASE}/#Integration", wait_until="networkidle", timeout=20000)
            await asyncio.sleep(5)
            
            # Wait for ExtJS to load
            content = await page.content()
            print(f"  Page size: {len(content)}")
            
            # Find Integration menu/sub-menu items
            # ExtJS uses .x-* classes for components
            # Menu items are typically .x-menu-item or .x-grid-item
            print("\n=== Finding Integration UI elements ===")
            
            # Look for all elements with "Integration" text
            int_elements = await page.evaluate('''() => {
                const elements = [];
                const all = document.querySelectorAll('*');
                for (const el of all) {
                    if (el.children.length === 0 && el.textContent && 
                        el.textContent.trim().toLowerCase().includes('integration') &&
                        el.textContent.trim().length < 50) {
                        elements.push({
                            tag: el.tagName,
                            text: el.textContent.trim(),
                            class: el.className,
                            id: el.id,
                            href: el.href || ''
                        });
                    }
                }
                return elements;
            }''')
            print(f"  Integration text elements: {len(int_elements)}")
            for el in int_elements[:10]:
                print(f"    {el['tag']}#{el['id']} class={el['class'][:30]} text='{el['text'][:40]}'")
            
            # Look for SQL/Execute elements
            sql_elements = await page.evaluate('''() => {
                const elements = [];
                const all = document.querySelectorAll('*');
                for (const el of all) {
                    if (el.children.length === 0 && el.textContent) {
                        const t = el.textContent.trim().toLowerCase();
                        if ((t.includes('sql') || t.includes('execute') || 
                             t.includes('query') || t.includes('database') ||
                             t.includes('external') || t.includes('program')) &&
                            t.length < 50) {
                            elements.push({
                                tag: el.tagName,
                                text: el.textContent.trim(),
                                class: el.className,
                                id: el.id
                            });
                        }
                    }
                }
                return elements;
            }''')
            print(f"\n  SQL/Execute text elements: {len(sql_elements)}")
            for el in sql_elements[:10]:
                print(f"    {el['tag']}#{el['id']} class={el['class'][:30]} text='{el['text'][:40]}'")
            
            # Click on Integration menu item to expand
            print("\n=== Clicking Integration menu ===")
            clicked = await page.evaluate('''() => {
                const items = document.querySelectorAll('a, li, span, div');
                for (const el of items) {
                    if (el.textContent && el.textContent.trim() === 'Integration' && 
                        (el.tagName === 'A' || el.tagName === 'LI' || el.className.includes('menu'))) {
                        el.click();
                        return 'clicked: ' + el.tagName + '.' + el.className.substring(0,30);
                    }
                }
                return 'not found';
            }''')
            print(f"  {clicked}")
            await asyncio.sleep(3)
            await page.screenshot(path="/tmp/integration_clicked.png")
            
            # After clicking Integration, look for sub-menu items
            submenu = await page.evaluate('''() => {
                const items = [];
                const all = document.querySelectorAll('*');
                for (const el of all) {
                    if (el.children.length === 0 && el.textContent) {
                        const t = el.textContent.trim();
                        if (t.length > 3 && t.length < 50 && 
                            (t.includes('SQL') || t.includes('Execute') || 
                             t.includes('Query') || t.includes('Database') ||
                             t.includes('Process') || t.includes('Step') ||
                             t.includes('Connection') || t.includes('External'))) {
                            items.push({tag: el.tagName, text: t, id: el.id, class: el.className.substring(0,30)});
                        }
                    }
                }
                return items;
            }''')
            print(f"\n  Sub-menu items after click: {len(submenu)}")
            for el in submenu[:15]:
                print(f"    {el['tag']}#{el['id']} '{el['text'][:40]}'")
            
            # Try to click on "Connection" or "Process" sub-menu
            for target in ["Connection", "Process", "Step", "Execute SQL", "SQL Query"]:
                result = await page.evaluate(f'''() => {{
                    const items = document.querySelectorAll('*');
                    for (const el of items) {{
                        if (el.children.length === 0 && el.textContent && 
                            el.textContent.trim().toLowerCase() === '{target.lower()}') {{
                            el.click();
                            return 'clicked: ' + el.tagName + '#' + el.id;
                        }}
                    }}
                    return 'not found: {target}';
                }}''')
                if "clicked" in result:
                    print(f"  {result}")
                    await asyncio.sleep(3)
                    await page.screenshot(path=f"/tmp/after_{target.replace(' ','_')}.png")
                    break
            
            # Look for SQL textarea/input after navigation
            print("\n=== Looking for SQL input ===")
            textareas = await page.query_selector_all("textarea")
            print(f"  Textareas: {len(textareas)}")
            for i, ta in enumerate(textareas[:5]):
                info = await ta.evaluate("el => ({name: el.name, id: el.id, class: el.className.substring(0,30)})")
                print(f"    [{i}] {info}")
            
            # Check for ExtJS form fields
            form_fields = await page.evaluate('''() => {
                const fields = [];
                document.querySelectorAll('input, textarea, .x-form-field, .x-form-text').forEach(el => {
                    fields.push({tag: el.tagName, name: el.name || '', id: el.id || '', type: el.type || '', class: el.className.substring(0,40)});
                });
                return fields;
            }''')
            print(f"  Form fields: {len(form_fields)}")
            for f in form_fields[:10]:
                print(f"    {f['tag']} name={f['name']} id={f['id']} type={f['type']}")
            
            # Print AJAX
            print(f"\n=== AJAX ({len(ajax_logs)}) ===")
            for log in ajax_logs[:15]:
                print(f"  {log['m']:4s} {log['u']} → {log['s']}")
            
        except Exception as e:
            print(f"\n❌ Error: {e}")
            import traceback; traceback.print_exc()
            await page.screenshot(path="/tmp/error.png")
        finally:
            await browser.close()

asyncio.run(main())
