import unittest

import cv2
from selenium.common.exceptions import NoSuchElementException, TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from appium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from Android_Topsap_Library.elements_config import *
from Android_Topsap_Library.logger import log
import time
import sys, os
from PIL import Image

# 将默认编码设置为utf-8


# reload(sys)
# sys.setdefaultencoding('utf-8')
'''
页面基类,封装各个界面的通用方法
'''
# 创建pictures文件夹
cur_path = os.path.dirname(os.path.realpath(__file__))
pic_path = os.path.join(cur_path, 'pictures')
# 如果不存在这个logs文件夹,就自动创建一个
if not os.path.exists(pic_path): os.mkdir(pic_path)


class BasePage(unittest.TestCase):
    def __init__(self):
        pass

    exit_button_id = common_page_element.get("exit_app_id")
    popwindow_title_id = popwindow_element.get("popwindow_title_id")

    def get_android_driver(self, platformVersion="4.2"):
        '''
        配置Android客户端的driver
        :param platformVersion:
        :return:返回客户端配置字典
        '''
        desired_caps = {}
        desired_caps['platformName'] = 'Android'
        desired_caps['platformVersion'] = '5.1.1'
        desired_caps['deviceName'] = 'Android Emulator'
        # desired_caps['platformVersion'] = '10'
        # desired_caps['deviceName'] = 'test nova'
        desired_caps['appPackage'] = '包名'
        desired_caps['appActivity'] = '起始页activity'
        # 'automationName':'Selendroid'
        desired_caps['automationName'] = 'Uiautomator2'
        desired_caps['noReset'] = "True"
        return desired_caps

    def open_driver(self):
        '''
        启动driver,建立appium与模拟器的session
        :return:
        '''
        desired_caps = self.get_android_driver()
        self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
        time.sleep(8)
        return self.driver

    def close_App(self):
        '''
        退出客户端
        :return:
        '''
        self.driver.close_app()

    def open_App(self):
        '''
        启动客户端
        :return:
        '''
        self.driver.launch_app()

    def close_driver(self):
        '''
        退出driver
        :return:
        '''
        self.driver.quit()

    def find_element(self, *loc):
        '''
        重写的定位元素方法
        :param loc:查找元素的元组如 (By.ID,'com.topsec.topsap:id/ip')
        :return:
        '''
        try:
            WebDriverWait(self.driver, 10, 0.5).until(EC.visibility_of_element_located(loc))
            return self.driver.find_element(*loc)
        except:
            self.take_screen_shot("find_element")
            log.error("查找不到%s为%s的元素" % loc)

    def find_elements(self, *loc):
        '''
        重写查找多个元素方法(多个元素具有相同属性)
        :param loc:查找元素的元组如 (By.ID,'com.topsec.topsap:id/ip')
        :return:
        '''
        try:
            WebDriverWait(self.driver, 10, 0.5).until(EC.visibility_of_element_located(loc))
            return self.driver.find_elements(*loc)
        except:
            log.error("查找不到%s为%s的元素列表" % loc)

    def is_element_exits(self, *loc):
        '''
        判断元素是否存在
        :param loc: 查找元素的元组如 (By.ID,'com.topsec.topsap:id/ip')
        :return: True,元素存在,False元素不存在
        '''
        flag = None
        try:
            WebDriverWait(self.driver, 5, 0.5).until(EC.visibility_of_element_located(loc))
            flag = True
            return flag
        except NoSuchElementException:
            flag = False
            return flag
        except TimeoutException:
            flag = False
            return flag
        finally:
            print(flag)
            return flag

    def click_exit_button(self):
        '''
        点击退出按钮退出APP
        :return:
        '''
        self.click_by_id(self.exit_button_id)
        self.click_by_text("确定")

    def page_switch(self, page_name):
        '''
        切换页面
        :param page_name: 要切换的页面名称
        :return:
        '''
        page_element = self.find_element(By.XPATH, "//*[@text='%s']" % page_name)
        page_element.click()

    def install_app(self, apk_name):
        '''
        安装app
        :return:
        '''
        if self.is_app_installed():
            self.uninstall_app()
        app_path = os.path.dirname(os.path.realpath(__file__)) + "\\app\\" + apk_name + ".apk"
        result_file = os.popen("adb install " + app_path)
        result = result_file.read()
        if "Success" in result:
            log.info("应用安装成功")
        elif "Failure" in result:
            log.error("应用安装失败")

    def uninstall_app(self):
        """
        卸载应用
        :return:
        """
        result_file = os.popen("adb uninstall com.topsec.topsap")
        result = result_file.read()
        if "Success" in result:
            log.info("应用卸载成功")
        elif "Failure" in result:
            log.error("应用卸载失败")

    def is_app_installed(self):
        '''
        判断应用是否已经安装
        :return: True,已经安装,False未安装
        '''
        result = os.popen("adb shell pm list package")
        result = result.read().split("\r\n")
        if "package:com.topsec.topsap" in result:
            log.info("应用已安装")
            return True
        else:
            log.info("应用未安装")
            return False

    def take_screen_shot(self, func_name):
        '''
        对页面进行截图
        :param func_name:调用截图的方法的名字
        :return:
        '''
        # timestr = time.strftime("%Y-%m-%d_%H_%M_%S")
        self.driver.get_screenshot_as_file(pic_path + '\%s.png' % func_name)

    def is_toast_exist(self, message, fuzzy="False"):
        '''
        判断toast是否存在
        :param message: toast的文本
        :param fuzzy: 是否模糊匹配,"False"精确匹配,"True"模糊匹配
        :return: 返回True表示存在,False不存在
        '''
        try:
            if fuzzy == "False":
                element = WebDriverWait(self.driver, 10, 0.01).until(
                    EC.presence_of_all_elements_located((By.XPATH, '//*[@text=\'{}\']'.format(message))))
            elif fuzzy == "True":
                element = WebDriverWait(self.driver, 10, 0.01).until(
                    EC.presence_of_all_elements_located((By.XPATH, '//*[contains(@text,\'{}\')]'.format(message))))
                print(element[0].text)
            return True
        except Exception as e:
            log.error(e)
            return False

    def is_text_exits(self, text, except_value):
        '''
        判断文本是否存在
        :param text:要检测的文本
        :param except_value:期望值,如果期望文本存在填写"True",不期望"False"
        eg:is_text_exits("登录","False"),期望登录文本不存在
        :return:
        '''
        is_text_exits = self.is_element_exits(By.XPATH, "//*[@text='%s']" % text)
        if except_value == "True" and is_text_exits:
            return True
        elif except_value == "False" and not is_text_exits:
            return True
        elif except_value == "True" and not is_text_exits:
            return False
        elif except_value == "False" and is_text_exits:
            return False

    def press_back(self):
        '''
        按手机返回按钮返回
        :return:
        '''
        self.driver.press_keycode(keycode=4)

    def click_by_text(self, text):
        '''
        通过文本点击
        :param text:要点击的控件的文本,需要当前界面唯一
        :return:
        '''
        self.find_element(By.XPATH, "//*[@text='%s']" % text).click()

    def click_by_id(self, element_id):
        '''
        通过id点击
        :param element_id: 要点击的控件的id,需要当前界面唯一
        :return:
        '''
        self.find_element(By.ID, element_id).click()

    def input_text_by_id(self, element_id, text):
        '''
        输入文本
        :param element_id: 要输入文本的控件的id,需要当前界面唯一
        :param text:要输入的文本
        :return:
        '''
        self.find_element(By.ID, element_id).send_keys(text)

    def choiceOptions(self, optionsname):
        '''
        处理弹窗选项点击事件
        :param typename:选项名
        :return:
        '''
        self.click_by_text(optionsname)
        # options_list = self.find_elements(By.ID, self.options_list_id)
        # for options in options_list:
        #     if options.text == optionsname:
        #         options.click()
        #         break
        #     else:
        #         continue

    def check_by_text_contains(self, text1, text2):
        '''
        检测文本1是否在文本2中
        :param text1: 要检测的文本
        :param text2: 捕获到的文本
        :return: True,文本1在文本2中存在,False,不存在
        '''
        if text1 in text2:
            return True
        else:
            return False

    def handle_popwindow(self, click_text):
        '''
        处理弹窗
        :param click_text: 弹窗要点击的文本
        :return:
        '''
        loc = ("xpath", "//*[@text='%s']" % click_text)
        try:
            e = WebDriverWait(self.driver, 5, 0.5).until(EC.presence_of_element_located(loc))
            e.click()
        except:
            pass

    def get_keynumber_location(self, secret_text):
        '''
        获取字母对应位置
        :return:返回template在image中的的bound参数
        '''
        keynum = pic_path + "\keynum.png"  # 键盘图片
        image = cv2.imread(keynum)
        key = cur_path + "\keyboard\%s.png" % secret_text  # 数字键图片
        template = cv2.imread(key)
        h, w = template.shape[:2]  # 字母图片尺寸
        result = cv2.matchTemplate(image, template, cv2.TM_CCOEFF_NORMED)  # 图片对比
        min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)  # 对比结果最大值最小值以及位置
        br = (max_loc[0] + w, max_loc[1] + h)
        return max_loc, br

    def click_position(self, secret_text):
        '''
        确定点击位置
        :param password: 口令密码
        :return:返回点击位置position
        '''
        position = self.get_safekeyborad_letter_position(secret_text)
        self.driver.tap(position)  # 点击

    def open_desk(self):
        desired_caps = {}
        desired_caps['platformName'] = 'Android'
        # desired_caps['platformVersion'] = '5.1.1'
        # desired_caps['deviceName'] = 'Android Emulator'
        desired_caps['platformVersion'] = '10'
        desired_caps['deviceName'] = 'test nova'
        desired_caps['appPackage'] = 'com.huawei.android.launcher'
        desired_caps['appActivity'] = '.unihome.UniHomeLauncher'
        # desired_caps['appPackage'] = 'com.vphone.launcher'
        # desired_caps['appActivity'] = '.Launcher'
        desired_caps['automationName'] = 'Uiautomator2'
        desired_caps['noReset'] = "True"
        self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
        time.sleep(5)
        return self.driver

    def press_home(self):
        '''
        按home健将应用置于后台
        :return:
        '''
        self.driver.press_keycode(keycode=3)

    def get_safekeyborad_letter_position(self, letter):
        '''
        确定点击位置
        :param password: 口令密码
        :return:返回点击位置position
        '''
        time.sleep(3)
        self.cut_safekeyboard_pic()
        a, b = self.get_keynumber_location(letter)  # template在image中的的bound参数
        x = a[0] + b[0]
        y = b[1] + a[1]
        position = (x / 2, y / 2 + 1536)
        return [position]

    def click_screen_center(self):
        '''
        点击屏幕中心点坐标
        :return:
        '''
        width = self.driver.get_window_size()['width']
        height = self.driver.get_window_size()['height']
        self.driver.tap([(width / 2, height / 2)])

    def start_AndFTP(self):
        '''
        启动AndFtp
        :return:
        '''
        self.driver.start_activity("lysesoft.andftp", "lysesoft.andftp.SettingsActivity")

    def start_topsap(self):
        '''
        启动AndFtp
        :return:
        '''
        self.driver.start_activity("com.topsec.topsap", "com.topsec.topsap.ui.WelcomeActivity")

    def cut_safekeyboard_pic(self):
        time.sleep(2)
        # self.find_elements(By.CLASS_NAME,"android.widget.TableLayout")[0]

        self.take_screen_shot("keynum1")
        im = Image.open(os.path.join(pic_path + "\\keynum1.png"))
        im = im.crop((0, 1536, 1080, 1920))
        im.save(pic_path + "/keynum.png")


if __name__ == '__main__':
    b = BasePage()
    # b.install_app("TopSAP(3.4.2.20.0.4)")
    # b.cut_safekeyboard_pic()
    driver = b.open_desk()
    b.start_topsap()
    b.click_by_id("com.topsec.topsap:id/btn_login")
    # print(b.is_element_exits(By.ID, "com.topsec.topsap:id/btn_login"))
    # b.click_by_id("com.topsec.topsap:id/tv_other_login")
    # print(b.is_element_exits(By.XPATH, "//*[@text='%s']" % "口令"))

    # b.start_AndFTP()
    # b.click_by_text("AndFTP")
    # time.sleep(3)
    # b.click_by_text("172.18.40.26")
    # time.sleep(3)
    # b.press_back()
    # b.press_back()
    # b.press_home()
    # b.close_driver()
    # driver.press_keycode(keycode=3)

    # result_file = os.popen("adb uninstall com.topsec.topsap")
    # result = result_file.read()
    # print result