# -*- coding: UTF-8 -*-
import os
import time
import platform
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver import ActionChains
from selenium.webdriver.support.select import Select
from base_framework.public_tools.read_config import get_current_config

cull_path = os.path.dirname(os.path.abspath(__file__))
plugs = os.path.abspath(os.path.join(cull_path, '../{}'.format('/platform_tools/plugins/headerenv.crx')))
DEFAULT_TIMEOUT = 5


class SeleniumWebUI:
    def __init__(self):
        self.driver = None
        self.action = None # 用于鼠标类事件
        self.business = get_current_config(section="run_evn_name", key="current_business")
        self.jira_id = get_current_config(section="run_jira_id", key="huohua-podenv")
        self.feature = get_current_config(section="run_jira_id", key="huohua-feature")
        # print(self.jira_id)

    def web_open_browser(self, url="", browser_type="chrome", enable_image=True, station='web'):
        """
        | 功能说明： | 打开浏览器，默认chrome |
        | 输入参数： | url | 网址，默认为空：仅打开浏览器 |
        |          | browser_type | 浏览器类型：chrome,firefox,edge |
        |          | enable_image | 浏览器是否加载图片 |
        |          | station | 浏览器模式：web：web模式，m：手机模式 |
        | 作者信息： | 谢祥益 | 2022.06.01   |
        """
        if browser_type == "chrome":
            options = webdriver.ChromeOptions()
            if platform.system() == 'Linux':
                default_driver_path = r'/home/chrome_home/chromedriver'
                options.add_argument("--headless")
                options.add_argument("--no-sandbox")
                options.add_argument('--disable-gpu')
                options.add_argument('--disable-dev-shm-usage')
                self.driver = webdriver.Chrome(executable_path=default_driver_path, options=options)
            else:
                # 将正确的chrome driver版本放在python根目录下
                options.add_extension(plugs)
                if not enable_image:
                    options.add_argument('blink-settings=imagesEnabled=false')
                    print('当前为无图片模式')
                if station == 'm':
                    options.add_experimental_option('mobileEmulation', {'deviceName': 'iPhone 12 Pro'})
                self.driver = webdriver.Chrome(options=options)
        elif browser_type == "firefox":
            self.driver = webdriver.Firefox()
        elif browser_type == "edge":
            self.driver = webdriver.Edge()
        else:
            raise Exception("传入的浏览器类型不正确,正确的浏览器类型(chrome, firefox, edge)")
        if len(url) > 0:
            self.web_open_url(url=url)
        self.action = ActionChains(self.driver)

    def web_open_url(self, url):
        """
        | 功能说明： | 打开链接并最大化浏览器 |
        | 输入参数： | url | 访问地址 |
        | 作者信息： | 谢祥益 | 2022.06.01   |
        """
        if not self.driver:
            self.web_open_browser()
        if self.jira_id.lower() not in ('', 'qa'):
            # 判断并添加独立环境
            self.web_set_independent_environment()
        self.driver.maximize_window()
        self.driver.get(url)

    def web_close_browser(self):
        """
        | 功能说明： | 关闭浏览器，但注意并没有销毁driver对象 |
        | 输入参数： |  无  |
        | 作者信息： | 谢祥益 at 2022.06.01   |
        举例说明：
        """
        self.driver.quit()

    def web_refresh_page(self):
        """
        | 功能说明： | 刷新浏览器当前页面 |
        | 输入参数： |  |
        | 作者信息： | 谢祥益 at 2022.06.01   |
        """
        self.driver.refresh()

    def web_switch_handle(self, index):
        """
        | 功能说明： | 切换浏览器页面标签，适用于新开页面，或多页面操作 |
        | 输入参数： | index | 标签索引 |
        | 作者信息： | 谢祥益 | 2022.06.01    |
        """
        handles = self.driver.window_handles
        self.driver.switch_to_window(handles[index])

    def web_get_cookie(self):
        """
        | 功能说明： | 返回浏览器当前application的cookie |
        | 输入参数： |  |
        | 作者信息： | 谢祥益 at 2022.06.01  |
        """
        return self.driver.get_cookies()

    def web_find_element(self, locator, timeout=DEFAULT_TIMEOUT, raise_exception=True):
        """
        | 功能说明： | 传入元素定位器，定位到该元素，返回第一个元素 |
        | 输入参数： | locator | 元素路径 |
        |          | timeout | 超时时间，默认10秒 |
        | 作者信息： | 谢祥益 | 2022.06.01 |
        """
        if not isinstance(locator, tuple):
            locator = (By.XPATH, locator)
        element = WebDriverWait(self.driver, timeout).until(ec.presence_of_element_located(locator),
                                                            message=['The element is not exist,please check....\n'
                                                                     'element xpath:{}'.format(locator)
                                                                     if raise_exception else None])
        return element

    def web_find_elements(self, locator, timeout=DEFAULT_TIMEOUT, raise_exception=True):
        """
        | 功能说明： | 传入元素定位器，定位到该元素，返回所有元素 |
        | 输入参数： | locator | 元素路径 |
        |          | timeout | 超时时间，默认10秒 |
        |          | raise_exception | 当找不到元素时：True-阻断报错(默认)，False-返回空list |
        | 作者信息： | 谢祥益 | 2022.06.01 |
        """
        if not isinstance(locator, tuple):
            locator = (By.XPATH, locator)
        element = []
        try:
            element = WebDriverWait(self.driver, timeout).until(ec.presence_of_all_elements_located(locator))
        except:
            if raise_exception:
                raise Exception("The element is not exist,please check....\n element xpath:{}".format(locator))
        return element

    def web_click_element(self, locator, timeout=DEFAULT_TIMEOUT):
        """
        | 功能说明： | 传入元素定位器，定位到该元素，普通方法点击 |
        | 输入参数： | locator | 元素路径 |
        |          | timeout | 超时时间，默认10秒 |
        | 作者信息： | 谢祥益 | 2022.06.01 |
        """
        element = self.web_find_element(locator, timeout)
        element.click()

    def web_click_elements(self, locator, timeout=DEFAULT_TIMEOUT):
        """
        | 功能说明： | 点击所有元素 |
        | 输入参数： | locator | 元素路径 |
        |          | timeout | 超时时间，默认10秒 |
        | 作者信息： | 谢祥益 | 2022.06.01 |
        """
        elements = self.web_find_elements(locator, timeout)
        for element in elements:
            element.click()

    def web_click_element_by_js(self, locator=None, element=None, timeout=DEFAULT_TIMEOUT):
        """
        | 功能说明： | 传入元素定位器，定位到该元素，以JS的方式点击 |
        | 输入参数： | locator | 元素路径，当没有element时输入  |
        |          | element | 元素对象，当没有locator时输入  |
        |          | timeout | 超时时间，默认10秒 |
        | 作者信息： | 谢祥益 | 2022.06.01 |
        """
        if not element and locator:
            obj = self.web_find_element(locator, timeout)
            self.driver.execute_script("arguments[0].click();", obj)
        elif element and not locator:
            self.driver.execute_script("arguments[0].click();", element)
        else:
            raise Exception('不支持的传参方式，locator和element必须且只能传一个')

    def web_move_element_to_top(self, locator, timeout=DEFAULT_TIMEOUT):
        """
        | 功能说明： | 将指定元素滑动到当前页面顶部 |
        | 输入参数： | locator | 元素路径 |
        |          | timeout | 超时时间，默认10秒 |
        | 作者信息： | 谢祥益 | 2022.08.12 |
        """
        element = self.web_find_element(locator, timeout)
        self.driver.execute_script("arguments[0].scrollIntoView();", element)

    def web_move_element_to_bottom(self, locator, timeout=DEFAULT_TIMEOUT):
        """
        | 功能说明： | 将指定元素滑动到当前页面底部 |
        | 输入参数： | locator | 元素路径 |
        |          | timeout | 超时时间，默认10秒 |
        | 作者信息： | 谢祥益 | 2022.08.12 |
        """
        element = self.web_find_element(locator, timeout)
        self.driver.execute_script("arguments[0].scrollIntoView(false);", element)

    def web_move_to_top(self):
        """
        | 功能说明： | 滑动到当前页面顶部 |
        | 作者信息： | 谢祥益 | 2022.08.12 |
        """
        self.driver.execute_script("window.scrollTo(document.body.scrollHeight,0)")

    def web_move_to_bottom(self):
        """
        | 功能说明： | 滑动到当前页面底部 |
        | 作者信息： | 谢祥益 | 2022.08.12 |
        """
        self.driver.execute_script("window.scrollTo(0,document.body.scrollHeight)")

    def web_send_keys(self, locator, text, timeout=DEFAULT_TIMEOUT):
        """
        | 功能说明： | 传入元素定位器，定位到该元素，清空输入框，写入text |
        | 输入参数： | locator | 元素路径 |
        |          | text    | 输入内容  |
        |          | timeout | 超时时间，默认10秒 |
        | 作者信息： | 谢祥益   | 2022.06.01 |
        """
        element = self.web_find_element(locator, timeout)
        element.send_keys(Keys.CONTROL, 'a')
        element.send_keys(text)

    def web_get_element_text(self, locator, timeout=DEFAULT_TIMEOUT):
        """
        | 功能说明： | 传入元素定位器，定位到该元素，返回该元素的文本值 |
        | 输入参数： | locator | 元素路径 |
        |          | timeout | 超时时间，默认10秒 |
        | 作者信息： | 谢祥益   | 2022.06.01 |
        """
        element = self.web_find_element(locator, timeout)
        return element.text

    def web_click_single_box(self, locator, timeout=DEFAULT_TIMEOUT):
        """
        | 功能说明： | 传入单选框元素定位器，定位到该元素，依次点击单选框 |
        | 输入参数： | locator | 元素路径 |
        |          | timeout | 超时时间，默认10秒 |
        | 作者信息： | 谢祥益   | 2022.06.01 |
        """
        elements = self.web_find_elements(locator, timeout)
        for element in elements:
            self.driver.execute_script("arguments[0].click();", element)
            time.sleep(1.5)

    def web_select_drop_down_box(self, locator, index=0, timeout=DEFAULT_TIMEOUT):
        """
        | 功能说明： | 传入下拉框定位器，定位到该元素，选择下拉框的第index个选项 |
        | 输入参数： | locator | 元素路径 |
        |          | index   | 第几个元素的下标  |
        |          | timeout | 超时时间，默认10秒 |
        | 作者信息： | 谢祥益   | 2022.06.01 |
        """
        select = Select(self.web_find_element(locator, timeout))
        select.select_by_index(index)

    def web_click_checkbox(self, locator, timeout=DEFAULT_TIMEOUT):
        """
        | 功能说明： | 传入多选框元素定位器，定位到该元素，全选 |
        | 输入参数： | locator | 元素路径 |
        |          | timeout | 超时时间，默认10秒 |
        | 作者信息： | 谢祥益   | 2022.06.01 |
        """
        checkbox = self.web_find_elements(locator, timeout)
        for i in checkbox:
            if not i.is_selected():
                i.click()

    def web_upload_file(self, locator, path, timeout=DEFAULT_TIMEOUT):
        """
        | 功能说明： | 传入元素定位器，定位到该元素，传入文件路径，只适用于input标签 |
        | 输入参数： | locator | 元素路径 |
        |          | path    | 文件完整路径 |
        |          | timeout | 超时时间，默认10秒 |
        | 作者信息： | 谢祥益   | 2022.06.01 |
        """
        element = self.web_find_element(locator, timeout)
        element.send_keys(path)

    def web_move_windows(self, x=0, y=0):
        """
        | 功能说明： | 传滑动窗口 |
        | 输入参数： | x        | x轴距离 |
        |          | y        | y轴距离 |
        | 作者信息： | 谢祥益    | 2022.06.01 |
        """
        self.driver.execute_script("window.scrollBy({},{})".format(x, y))

    def web_go_to_previous_page(self):
        """
        | 功能说明： | 返回上一页（浏览器工具栏向左箭头） |
        | 输入参数： | 无 |
        | 作者信息： | 谢祥益  at 2022.06.01 |
        """
        self.driver.back()

    def web_go_to_next_page(self):
        """
        | 功能说明： | 前进一页（浏览器工具栏向右箭头） |
        | 输入参数： | 无 |
        | 作者信息： | 谢祥益  at 2022.06.01 |
        """
        self.driver.forward()

    def web_close_current_page(self):
        """
        | 功能说明： | 关闭当前窗口页面 |
        | 输入参数： | 无 |
        | 作者信息： | 谢祥益  at 2022.06.01 |
        """
        self.driver.close()

    def web_get_window_title(self):
        """
        | 功能说明： | 获取当前浏览器标题 |
        | 输入参数： | 无 |
        | 作者信息： | 谢祥益  at 2022.06.01 |
        """
        return self.driver.title

    def web_get_element_attribute_value(self, locator, attr: str, timeout=DEFAULT_TIMEOUT):
        """
        | 功能说明： | 获取元素属性值 |
        | 输入参数： | locator | 元素路径 |
        |          | attr    | 属性名 |
        |          | timeout | 超时时间，默认10秒 |
        | 作者信息： | 谢祥益   | 2022.06.01 |
        """
        obj = self.web_find_element(locator, timeout=timeout)
        attr_value = obj.get_attribute(attr)
        return attr_value

    def web_modify_tag_attribution(self, locator, attr, value, timeout=DEFAULT_TIMEOUT):
        """
        | 功能说明： | 修改页签属性 |
        | 输入参数： | locator | 元素路径 |
        |          | attr    | 修改属性名 |
        |          | value   | 修改后的值 |
        |          | timeout | 超时时间，默认10秒 |
        | 作者信息： | 谢祥益   | 2022.06.01 |
        """
        obj = self.web_find_element(locator, timeout)
        self.driver.execute_script("arguments[0].{attr}={value};".format(attr=attr, value=value), obj)

    def web_input_to_readonly_tag(self, locator, text, timeout=DEFAULT_TIMEOUT):
        """
        | 功能说明： | 带只读属性的标签输入 |
        | 输入参数： | locator | 元素路径 |
        |          | text    | 输入内容 |
        |          | timeout | 超时时间，默认10秒 |
        | 作者信息： | 谢祥益   | 2022.06.01 |
        """
        obj = self.web_find_element(locator, timeout)
        self.driver.execute_script("arguments[0].removeAttribute('readonly');", obj)
        self.web_send_keys(locator=locator, text=text)

    def web_get_css_property_value(self, locator, css_property, timeout=DEFAULT_TIMEOUT):
        """
        | 功能说明： | 获取css属性值 |
        | 输入参数： | locator | 元素路径 |
        |          | text    | 输入内容 |
        |          | timeout | 超时时间，默认10秒 |
        | 作者信息： | 谢祥益   | 2022.07.08 |
        """
        obj = self.web_find_element(locator, timeout)
        value = obj.value_of_css_property(css_property)
        return value

    def web_take_screenshot(self, save_path, picture_name):
        """
        | 功能说明： | 截屏浏览器当前页面 |
        | 输入参数： | save_path      | 保存地址 |
        |          | picture_name   | 图片名称 |
        | 作者信息： | 谢祥益          | 2022.06.01 |
        """
        picture_path = os.path.join(save_path, picture_name + '.png')
        self.driver.get_screenshot_as_file(picture_path)

    def web_set_independent_environment(self):
        """
        | 功能说明： | 设置独立环境 |
        | 输入参数： | 无 |
        | 作者信息： | 谢祥益  at 2022.06.01 |
        """
        # 新增独立环境
        new_loc = ('xpath', '/html/body/div/div[3]/button/div/div/i')
        # 独立环境名称
        rule_name_loc = ('id', 'rule-name')
        # 规则类型
        rule_type_loc = ('xpath', '//*[@id="edit-page"]/div[2]/div[1]/div/div[2]/div[2]/div[2]/div[3]/div')
        # 头名称
        rule_header_name_loc = ('id', 'rule-headerName')
        # 头内容
        rule_header_value_loc = ('id', 'rule-headerValue')
        # 保存
        create_loc = ('xpath', '//*[@id="edit-page"]/div[2]/div[2]/div[2]/div[2]/button/div/div')

        self.driver.get("chrome-extension://eningockdidmgiojffjmkdblpjocbhgh/options/options.html")

        if self.jira_id and self.jira_id.lower()!='qa':
            rule_header_name = 'huohua-podenv'
            rule_header_value = self.jira_id
            self.web_click_element(new_loc)
            self.web_send_keys(rule_name_loc, self.jira_id)
            self.web_click_element(rule_type_loc)
            self.web_send_keys(rule_header_name_loc, rule_header_name)
            self.web_send_keys(rule_header_value_loc, rule_header_value)
            self.web_click_element(create_loc)
            rule_header_name = 'huohua-feature'
            rule_header_value = self.feature
            self.web_click_element(new_loc)
            self.web_send_keys(rule_name_loc, "front")
            self.web_click_element(rule_type_loc)
            self.web_send_keys(rule_header_name_loc, rule_header_name)
            self.web_send_keys(rule_header_value_loc, rule_header_value)
            self.web_click_element(create_loc)
        else:
            print("无独立环境！")

    def web_mouse_move_to_element(self, locator):
        """
        | 功能 | 移动鼠标到元素位置  |
        | 入参 | locator | 元素xpath路径 |
        | 说明 | 多次刷新页面 | 容易导致此方法失效，慎用... |
        |     | 必要时 | 可以尝试直接点击对应控件:web_click_element |
        """
        self.action.reset_actions()
        obj = self.web_find_element(locator=locator)
        self.action.move_to_element(obj)
        self.action.perform()

    def web_mouse_click(self):
        """功能：模拟鼠标点击"""
        self.action.click().perform()
        # self.action.perform()

    def web_check_element_exist(self, locator, quantity=1):
        """
        | 功能说明： | 检查页面元素是否存在：0-不存在，1-存在，>1-存在多少个，-1-仅判断存在不判断数量 |
        | 输入参数： | locator | 元素路径 |
        |          | quantity | 对应locator的元素有多少个, 传入-1则仅检查存在，不判断数量 |
        | 作者信息： | 吴勇刚 | 2022.08.01 |
        """
        if int(quantity) == 0: # 当检查元素不存在时，设计设置为2秒
            time_out = 2
        else:
            time_out = DEFAULT_TIMEOUT
        elements = self.web_find_elements(locator=locator, raise_exception=False, timeout=time_out)
        if quantity != -1:
            if len(elements) != int(quantity):
                raise Exception("the element [{}] expect exist {},but current is {}..."
                                .format(locator, quantity, len(elements)))
        else:
            if len(elements) == 0:
                raise Exception("the element is not exist：{}...".format(locator))

    def web_check_element_text(self, locator, exp_text):
        """
        | 功能说明： | 检查源文本是否正确 | 转为字符串比较 |
        | 输入参数： | locator | 元素路径 |
        |          | exp_text | 元素预期文本 |
        | 作者信息： | 吴勇刚   | 2022.08.01 |
        """
        act_text = self.web_get_element_text(locator=locator)
        if act_text != str(exp_text):
            raise Exception("The element [{}]'s text expect [{}],bug now it's [{}] "
                            .format(locator, exp_text, act_text))

    def web_check_element_attribute(self, locator, attr_name, exp_value):
        """
        | 功能说明： | 检查元素属性值是否正确 |
        | 输入参数： | locator | 元素路径 |
        |          | attr_name | 元素属性名称 |
        |          | exp_value | 元素预期属性值 |
        | 作者信息： | 吴勇刚   | 2022.08.01 |
        """
        act_value = self.web_get_element_attribute_value(locator=locator, attr=attr_name)
        if act_value != exp_value:
            raise Exception("The element [{}] attribute [{}]'s value expect [{}],bug now it's [{}] "
                            .format(locator, attr_name, exp_value, act_value))

    def web_get_current_url(self):
        """
        | 功能说明： | 检查源文本是否正确 | 转为字符串比较 |
        | 输入参数： | locator | 元素路径 |
        |          | exp_text | 元素预期文本 |
        | 作者信息： | 吴勇刚   | 2022.08.01 |
        """
        current_url = self.driver.current_url
        return current_url


if __name__ == '__main__':
    web_driver = SeleniumWebUI()
    vispark_url = "https://sparkle.qa.huohua.cn/intl/schedule"
    web_driver.web_open_url(url=vispark_url)
    url = web_driver.web_get_current_url()
    print(url)
    web_driver.web_close_browser()