import os
import re
import time
import socket
import pyperclip
import http.client
try:
    import chromedriver_autoinstaller as AutoChrome
except ImportError:
    os.system('python -m pip install --upgrade pip')
    os.system('python -m pip install chromedriver_autoinstaller')
    import chromedriver_autoinstaller as AutoChrome
try:
    from fake_useragent import UserAgent
except ImportError:
    os.system('python -m pip install --upgrade pip')
    os.system('python -m pip install fake_useragent')
    from fake_useragent import UserAgent
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.select import Select
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.remote.command import Command
try:
    from anticaptchaofficial.recaptchav2proxyless import *
except ImportError:
    os.system('python -m pip install --upgrade pip')
    os.system('python -m pip install anticaptchaofficial')
    from anticaptchaofficial.recaptchav2proxyless import *
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.common.action_chains import ActionChains


def get_status(driver):
    try:
        driver.execute(Command.STATUS)
        return "Alive"
    except (socket.error, http.client.CannotSendRequest):
        return "Dead"


def load_driver(chrome_options = None):
    # userAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36'
    # userAgentMo = 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1'
    # userAgent = UserAgent().random
    chrome_ver = AutoChrome.get_chrome_version().split('.')[0]
    chrome_driver_path = 'C:\\chromedriver\\'

    if not os.path.isdir('c:\\chromedriver'):
        os.mkdir('c:\\chromedriver')

    d = DesiredCapabilities.CHROME
    d['goog:loggingPrefs'] = { 'browser':'ALL' }
    if chrome_options is None:
        chrome_options = Options()
        chrome_options.add_argument('--window-position=850,0')
    # chrome_options.add_argument('headless')    # 창을 띄우지 않고 백그라운드에서 돌아가게 함
    # chrome_options.add_argument('window-size=1920x1080')    # 창 사이즈 설정
    # chrome_options.add_argument('--blink-settings=imagesEnabled=false')    # 이미지 로딩안함
    # chrome_options.add_argument(f"user-agent={userAgent}")
    
    # 속도향상 옵션
    # chrome_options.add_argument('disable-infobars')
    # chrome_options.add_argument('--disable-extensions')
    # chrome_options.add_argument('--disable-gpu')
    # prefs = {'profile.default_content_setting_values': {'cookies' : 2, 'images': 2, 'plugins' : 2, 'popups': 2, 'geolocation': 2, 'notifications' : 2, 'auto_select_certificate': 2, 'fullscreen' : 2, 'mouselock' : 2, 'mixed_script': 2, 'media_stream' : 2, 'media_stream_mic' : 2, 'media_stream_camera': 2, 'protocol_handlers' : 2, 'ppapi_broker' : 2, 'automatic_downloads': 2, 'midi_sysex' : 2, 'push_messaging' : 2, 'ssl_cert_decisions': 2, 'metro_switch_to_desktop' : 2, 'protected_media_identifier': 2, 'app_banner': 2, 'site_engagement' : 2, 'durable_storage' : 2}}
    # chrome_options.add_experimental_option('prefs', prefs)

    chrome_options.add_experimental_option("excludeSwitches", ["enable-logging"])                # 실험적옵션 추가 (제외스위치로 enable-logging을 제외함)
    try:
        driver = webdriver.Chrome(executable_path=f'c:\\chromedriver\\{chrome_ver}\\chromedriver.exe', options=chrome_options)
    except:
        AutoChrome.install(path=chrome_driver_path)
        driver = webdriver.Chrome(executable_path=f'c:\\chromedriver\\{chrome_ver}\\chromedriver.exe', options=chrome_options)
    return driver


def load_driver2(port=9222):
    import subprocess
    
    chrome_ver = AutoChrome.get_chrome_version().split('.')[0]
    chrome_driver_path = 'C:\\chromedriver\\'

    if not os.path.isdir('c:\\chromedriver'):
        os.mkdir('c:\\chromedriver')

    # userAgent = UserAgent().random
    try:
        subprocess.Popen(rf'C:\Program Files\Google\Chrome\Application\chrome.exe --remote-debugging-port={port} --user-data-dir="C:\chrometemp"')
    except:
        subprocess.Popen(rf'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe --remote-debugging-port={port} --user-data-dir="C:\chrometemp"')

    d = DesiredCapabilities.CHROME
    d['goog:loggingPrefs'] = { 'browser':'ALL' }
    chrome_options = Options()                                                                    # 옵션객체 생성
    chrome_options.add_experimental_option("debuggerAddress", f"127.0.0.1:{port}")
    # chrome_options.add_argument(f"user-agent={userAgent}")
    try:
        driver = webdriver.Chrome(executable_path=f'c:\\chromedriver\\{chrome_ver}\\chromedriver.exe', options=chrome_options)
    except:
        AutoChrome.install(path=chrome_driver_path)
        driver = webdriver.Chrome(executable_path=f'c:\\chromedriver\\{chrome_ver}\\chromedriver.exe', options=chrome_options)
    return driver


def load_cache_driver(userId, chrome_options = None):

    chrome_ver = AutoChrome.get_chrome_version().split('.')[0]
    chrome_driver_path = 'C:\\chromedriver\\'
    
    if not os.path.isdir('c:\\chromedriver'):
        os.mkdir('c:\\chromedriver')
    
    if chrome_options is None:
        chrome_options = Options()
        userDataFolder = 'c:/cache/{}'.format(userId)
        chrome_options.add_argument('--user-data-dir=' + userDataFolder)
        chrome_options.add_argument('--disk-cache-dir=' + userDataFolder)
    chrome_options.add_experimental_option("excludeSwitches", ["enable-logging"])
    try:
        driver = webdriver.Chrome(executable_path=f'c:\\chromedriver\\{chrome_ver}\\chromedriver.exe', options=chrome_options)
    except:
        AutoChrome.install(path=chrome_driver_path)
        driver = webdriver.Chrome(executable_path=f'c:\\chromedriver\\{chrome_ver}\\chromedriver.exe', options=chrome_options)
    return driver


def n_login(driver: WebDriver, nid, pwd):

    import requests

    driver.get('https://m.naver.com/aside/')
    
    time.sleep(.5)
    
    try:
        if driver.find_element(By.CSS_SELECTOR, '.MM_LOGINOUT').text == '로그아웃':
            return True
    except:
        pass

    driver.find_elements(By.CSS_SELECTOR, 'a[class="ss_a"]')[0].click()

    pyperclip.copy(nid)
    driver.find_elements(By.CSS_SELECTOR, '#id')[0].send_keys(Keys.CONTROL, 'v')
    time.sleep(0.5)

    pyperclip.copy(pwd)
    driver.find_elements(By.CSS_SELECTOR, '#pw')[0].send_keys(Keys.CONTROL, 'v')
    time.sleep(0.5)

    driver.find_elements(By.CSS_SELECTOR, 'button[class="btn_check"]')[0].click()
    driver.implicitly_wait(3)
    time.sleep(1)

    now_url = driver.current_url
    source = driver.page_source

    if 'https://m.naver.com/aside/' == now_url:
        return True

    elif 'idSafetyRelease' in now_url and '회원님의 아이디를 보호하고 있습니다.' in source:
        flag = '보호조치'
        requests.get(f'http://aaa.e-e.kr/problemid/insert.php?id={nid}&desc={flag}')
        return flag
    
    elif 'sleepId' in now_url and '회원님의 아이디는 휴면 상태로 전환되었습니다.' in source:
        flag = '휴면'
        requests.get(f'http://aaa.e-e.kr/problemid/insert.php?id={nid}&desc={flag}')
        return flag
    
    elif 'https://nid.naver.com/nidlogin.login' == now_url and '가입하지 않은 아이디이거나, 잘못된 비밀번호입니다.' in source:
        return False
    
    elif 'https://nid.naver.com/nidlogin.login' == now_url and '스팸성 홍보활동' in source:
        flag = '보호조치(스팸성 홍보활동)'
        requests.get(f'http://aaa.e-e.kr/problemid/insert.php?id={nid}&desc={flag}')
        return flag

    elif 'https://nid.naver.com/user2/help/contactInfo?m=viewPhoneInfo' == now_url and '회원정보에 사용할 휴대 전화번호를 확인해 주세요.' in source:
        return True

    else:
        return False


def daum_mail_login(driver, did, pwd):

    try:
        driver.get('https://logins.daum.net/accounts/signinform.do?url=https%3A%2F%2Fmail.daum.net%2F')
    except:
        driver.refresh()
    driver.implicitly_wait(5)
    time.sleep(1)

    pyperclip.copy(did)
    driver.find_element(By.CSS_SELECTOR, 'input[type="email"]').send_keys(Keys.CONTROL + 'v')
    pyperclip.copy(pwd)
    driver.find_element(By.CSS_SELECTOR, 'input[type="password"]').send_keys(Keys.CONTROL + 'v')
    time.sleep(.5)
    driver.find_element(By.CSS_SELECTOR, 'label[class="lab_check"]').click()
    time.sleep(.5)
    driver.find_element(By.CSS_SELECTOR, 'button[id="loginBtn"]').click()
    driver.implicitly_wait(5)
    time.sleep(1)

    now_url = driver.current_url

    # 카카오 통합계정이면 
    if now_url == 'https://logins.daum.net/accounts/login.do?slevel=1':

        # 로그인 창
        driver.get('https://accounts.kakao.com/login?continue=https%3A%2F%2Flogins.daum.net%2Faccounts%2Fksso.do%3Frescue%3Dtrue%26url%3Dhttps%253A%252F%252Fmail.daum.net%252F')
        driver.implicitly_wait(3)
        time.sleep(1)

        # 아이디 비밀번호 입력
        pyperclip.copy(did)
        driver.find_element(By.CSS_SELECTOR, 'input[validator="email_or_phone_or_kakaoid"]').send_keys(Keys.CONTROL + 'v')
        pyperclip.copy(pwd)
        driver.find_element(By.CSS_SELECTOR, 'input[validator="password"]').send_keys(Keys.CONTROL + 'v')
        time.sleep(.5)
        driver.execute_script(""" document.querySelector('input[name="stay_signed_in"]').click() """)
        time.sleep(.5)
        driver.find_element(By.CSS_SELECTOR, 'button[class="btn_g btn_confirm submit"]').click()
        driver.implicitly_wait(5)

        # 메일쓰기 버튼 나올때까지 대기
        WebDriverWait(driver, 10).until(expected_conditions.presence_of_element_located((By.CSS_SELECTOR, 'button[class="btn_comm btn_write"]')))
        time.sleep(1)

    else:

        try:
            WebDriverWait(driver, 10).until(expected_conditions.presence_of_element_located((By.CSS_SELECTOR, 'button[class="btn_comm btn_write"]')))
            time.sleep(1)
        except:
            driver.find_element(By.CSS_SELECTOR, 'a[id="afterBtn"]').click()
            driver.implicitly_wait(10)
            time.sleep(2)


def t_login(driver, tid, pwd):
    try:
        driver.find_element(By.CSS_SELECTOR, 'a[href="/login"]').click()
        driver.implicitly_wait(5)
        time.sleep(.5)

        pyperclip.copy(tid)
        driver.find_element(By.CSS_SELECTOR, 'input[type="text"]').send_keys(Keys.CONTROL, 'v')
        time.sleep(.5)
        pyperclip.copy(pwd)
        driver.find_element(By.CSS_SELECTOR, 'input[type="password"]').send_keys(Keys.CONTROL, 'v')
        time.sleep(.5)

        driver.find_element(By.CSS_SELECTOR, 'div[role="button"]').click()
        driver.implicitly_wait(5)
        time.sleep(.5)
    except:
        print('로그인이 되어 있습니다.')
    driver.get('https://twitter.com')
    time.sleep(1)
    if driver.current_url == 'https://twitter.com/home':
        return True
    else:
        return False


def scrollDownUntilPageEnd(driver, SCROLL_PAUSE_SEC = 1):
    
    # 스크롤 높이 가져옴
    try:
        last_height = driver.execute_script("return document.body.scrollHeight")
    except:
        return False
    while True:
        # 끝까지 스크롤 다운
        driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")

        # 1초 대기
        time.sleep(SCROLL_PAUSE_SEC)

        # 스크롤 다운 후 스크롤 높이 다시 가져옴
        new_height = driver.execute_script("return document.body.scrollHeight")
        if new_height == last_height:
            # 끝까지 스크롤 다운
            driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")

            # 1초 대기
            time.sleep(SCROLL_PAUSE_SEC)

            # 스크롤 다운 후 스크롤 높이 다시 가져옴
            new_height = driver.execute_script("return document.body.scrollHeight")
            if new_height == last_height:
                break
            break
        last_height = new_height
    return True


def solve_reCAPTCHA(driver):

    try:
        target_site_url = driver.current_url
        target_site_key = driver.execute_script('''return document.querySelector('[data-sitekey]').getAttribute('data-sitekey');''')
    except:
        print('해당 사이트의 reCAPTCHA Key를 찾을 수 없습니다.')
        return False

    API_KEY = 'b336be7de932b65c877403893a382713'

    solver = recaptchaV2Proxyless()
    solver.set_verbose(1)
    solver.set_key(API_KEY)
    solver.set_website_url(target_site_url)
    solver.set_website_key(target_site_key)
    #set optional custom parameter which Google made for their search page Recaptcha v2
    #solver.set_data_s('"data-s" token from Google Search results "protection"')

    g_response = solver.solve_and_return_solution()
    if g_response != 0:
        # print("g-response: "+g_response)
        pass
    else:
        print("task finished with error "+solver.error_code)
    
    result_flag = driver.execute_script(f'''document.getElementById("g-recaptcha-response").innerHTML = "{g_response}"''')

    return True if result_flag == None else False


def http_remove(link: str):
    '''url의 http(s) 제거'''
    link = re.sub("(http|https)\:\/\/",'', link).strip('/')
    return link


def http_append(link: str):
    '''url에 https 추가'''
    return link if link.startswith('http') else "https://" + link

