import time,re,json,requests,io,random,subprocess
import numpy as np
from PIL import Image, ImageFilter
from scipy import ndimage
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.firefox.service import Service
o=Options(); o.set_preference('dom.webdriver.enabled',False)
o.set_preference('network.proxy.type',2); o.set_preference('network.proxy.autoconfig_url','http://127.0.0.1:9999/proxy.pac')

d=webdriver.Firefox(service=Service('./gd0371/geckodriver'), options=o)
def xdo(*a): subprocess.run(['xdotool',*map(str,a)],check=False)
try:
    d.set_window_position(0,0); d.set_window_size(1000,820)
    d.get('http://127.0.0.1:9999/geetest_page.html'); time.sleep(8)
    info=d.execute_script("""function r(s){var e=document.querySelector(s);if(!e)return null;var b=e.getBoundingClientRect();return {t:b.top,l:b.left,w:b.width,h:b.height,bg:getComputedStyle(e).backgroundImage};}return {bg:r('.geetest_bg'),slice:r('.geetest_slice'),slicebg:r('.geetest_slice_bg'),btn:r('.geetest_btn'),sx:window.mozInnerScreenX,sy:window.mozInnerScreenY};""")
    def dl(u):
        m=re.search(r'url\("?([^")]+)"?\)',u or '');return requests.get(m.group(1).replace('http://','https://'),timeout=20,verify=False).content
    bg=Image.open(io.BytesIO(dl(info['bg']['bg']))).convert('RGB'); sl=Image.open(io.BytesIO(dl(info['slicebg']['bg']))).convert('RGBA')
    g=np.array(bg.convert('L')).astype(np.float32); sa=np.array(sl); mask=sa[:,:,3]>128
    ys,xs=np.where(mask); ax0,ay0=xs.min(),ys.min(); aw,ah=xs.max()-ax0+1,ys.max()-ay0+1
    top=int(round((info['slice']['t']-info['bg']['t'])*bg.size[1]/info['bg']['h'])); top=max(0,min(bg.size[1]-ah,top))
    edges=np.array(bg.convert('L').filter(ImageFilter.FIND_EDGES)).astype(np.float32)
    contour=ndimage.binary_dilation(mask)&~ndimage.binary_erosion(mask)
    dark=g<100
    e_s=[];i_s=[];d_s=[]
    for x in range(0,bg.size[0]-aw-ax0+1):
        reg=g[top:top+ah,x+ax0:x+ax0+aw]; m2=mask[ay0:ay0+ah,ax0:ax0+aw]
        e=edges[top:top+ah,x+ax0:x+ax0+aw][contour[ay0:ay0+ah,ax0:ax0+aw]].mean()
        i=((dark[top:top+ah,x+ax0:x+ax0+aw]&m2).sum()/m2.sum())
        e_s.append((e,x)); i_s.append((i,x)); d_s.append((reg[m2].mean(),x))
    ex=sorted(e_s,reverse=True)[0][1]; ix=sorted(i_s,reverse=True)[0][1]; dx=sorted(d_s)[0][1]
    x=sorted([ex,ix,dx])[1]; print('edge',ex,'iou',ix,'dark',dx,'chosen',x)
    scale=info['bg']['w']/bg.size[0]; D=x*scale
    X=int(info['sx']+info['btn']['l']+info['btn']['w']/2); Y=int(info['sy']+info['btn']['t']+info['btn']['h']/2)
    print('D',D,'screen',X,Y)
    xdo('mousemove',X,Y); time.sleep(0.3); xdo('mousedown',1); time.sleep(0.2)
    n=40; moved=0
    for i in range(1,n+1):
        t=i/n; p=1-(1-t)**3; target=D*p
        xdo('mousemove',int(X+target),Y); time.sleep(random.uniform(0.015,0.035))
    xdo('mouseup',1); time.sleep(5)
    print('validate',d.execute_script('return window.validateResult'))
    print('res',d.execute_script("var e=document.querySelector('.geetest_result');return e?e.innerText:null"))
finally: d.quit()
