# -*-coding:utf-8 -*- #
# ---------------------------------------------------------------------------
# ProjectName:   test_58
# FileName:      read_excel.py
# Author:       xxxxxxx
# Datetime:     2024/1/4 10:05
# Description:
# 
# ---------------------------------------------------------------------------
import os

import openpyxl

from InterfaceAutoTest.common.read_ini import ReadIni
from InterfaceAutoTest.common.read_json import read_json
from InterfaceAutoTest.data_config.settings import *


class ReadExcel:
    def __init__(self, excel_path, table_name, case_data_path, expect_data_path, sql_data_path):
        """
        根据传入的文件路径，读取文件中的内容
        :param excel_path: excel文件的路径
        :param table_name: 工作表名称
        :param case_data_path: 用例json文件的路径
        :param expect_data_path: 期望json文件的路径
        :param sql_data_path: sql语句json文件的路径
        """
        # 读取json文件，使用read_json函数
        self.case_data_dict = read_json(case_data_path)
        self.expect_data_dict = read_json(expect_data_path)
        self.sql_data_dict = read_json(sql_data_path)

        try:
            # 加载excel的工作簿
            wb = openpyxl.load_workbook(excel_path)
            # 再获取工作表
            self.ws = wb[table_name]
        except:
            raise ValueError("传入的excel路径或者工作表的名称错误")

    def __get_cell_value(self, column: str, row: int) -> str:
        """根据列号和行号，获取单元格数据"""
        try:
            # 工作表["列号行号"].value
            cell_value = self.ws[column+str(row)].value
        except:
            raise ValueError("传入的列号或行号错误")
        else:
            # 判断单元格数据是否为None，如果是返回None
            if cell_value is None:
                return None
            # 判断单元格数据去掉前后空格，是否为空字符串，如果是返回None，如果不是返回去掉空格的字符串
            elif cell_value.strip():
                return cell_value.strip()

    def module_name(self, row):
        """根据行号，获取模块名称"""
        return self.__get_cell_value(MODULE_NAME, row)

    def api_name(self, row):
        """根据行号，获取接口名称"""
        return self.__get_cell_value(API_NAME, row)

    def case_req(self, row):
        """根据行号，获取请求方法"""
        return self.__get_cell_value(REQUEST_METHOD, row)

    def case_mime(self, row):
        """根据行号，获取用例的媒体类型"""
        mime_value = self.__get_cell_value(MIME, row)
        # 判断媒体类型的值是否为None，如果为None返回None，如果不为None，返回转小写的媒体类型的值
        if mime_value:
            return mime_value.lower()

    def case_url(self, row):
        """根据行号，获取用例请求的url"""
        # 获取用例请求的路径
        path = self.__get_cell_value(PATH, row)
        # 判断用例请求的路径的值是否为None，如果为None返回None，如果不为None，返回完整的url
        if path:
            return ReadIni().get_host("bpm") + path

    def case_data(self, row):
        """根据行号，获取用例数据"""
        # 获取用例数据的key
        case_data_key = self.__get_cell_value(CASE_DATA, row)
        # 判断用例数据的key是否不为None，如果是就提取用例数据，如果为None，返回None
        if case_data_key:
            # 获取模块名称
            module_name = self.module_name(row)
            # 获取接口名称
            api_name = self.api_name(row)
            # 返回用例数据
            return self.case_data_dict[module_name][api_name][case_data_key]

    def expect_data(self, row):
        """根据行号，获取用例数据"""
        # 获取期望数据的key
        expect_data_key = self.__get_cell_value(EXPECT_DATA, row)
        # 判断期望数据的key是否不为None，如果是就提取期望数据，如果为None，返回None
        if expect_data_key:
            # 获取模块名称
            module_name = self.module_name(row)
            # 获取接口名称
            api_name = self.api_name(row)
            # 返回期望数据
            return self.expect_data_dict[module_name][api_name][expect_data_key]

    def sql_data(self, row):
        """根据行号，获取用例数据"""
        # 获取sql语句的key
        sql_data_key = self.__get_cell_value(SQL_DATA, row)
        # 判断sql语句的key是否不为None，如果是就提取sql语句，如果为None，返回None
        if sql_data_key:
            # 获取模块名称
            module_name = self.module_name(row)
            # 获取接口名称
            api_name = self.api_name(row)
            # 返回sql语句
            return self.sql_data_dict[module_name][api_name][sql_data_key]

    def sql_type(self, row):
        """根据行号，获取sql语句的类型"""
        # 获取sql语句的类型的值
        sql_type_value = self.__get_cell_value(SQL_TYPE, row)
        # 判断sql语句的类型的值不为None，如果不为None，将sql语句的类型的值转小写返回，如果为None，返回None
        if sql_type_value:
            return sql_type_value.lower()

    def update_key(self, row):
        """根据行号，获取更新的key"""
        return self.__get_cell_value(UPDATE_KEY, row)

    def case_title(self, row):
        """根据行号，获取用例的标题"""
        return self.__get_cell_value(TITLE, row)

    def case_level(self, row):
        """根据行号，获取用例等级"""
        return self.__get_cell_value(LEVEL, row)

    def get_data(self):
        """将使用的数据存放到一个二维列表中"""
        # 创建空列表
        list_data = []
        # 循环所有的行，并取出每行的数据，再规避空行
        for row in range(2, self.ws.max_row+1):
            # 模块名称
            module_name = self.module_name(row)
            # 接口名称
            api_name = self.api_name(row)
            # 用例标题
            case_title = self.case_title(row)
            # 用例等级
            case_level = self.case_level(row)
            # 请求方法
            case_req = self.case_req(row)
            # 请求url
            case_url = self.case_url(row)
            # 请求媒体类型
            case_mime = self.case_mime(row)
            # 请求用例数据
            case_data = self.case_data(row)
            # 期望数据
            expect_data = self.expect_data(row)
            # sql语句类型
            sql_type = self.sql_type(row)
            # sql语句
            sql_data = self.sql_data(row)
            # 更新的key
            update_key = self.update_key(row)
            # 将数据存放在列表中
            row_list = [module_name, api_name, case_title, case_level, case_req, case_url, case_mime, case_data, expect_data, sql_type, sql_data, update_key]
            # 规避空行===每行的空数据不能超过5个
            if row_list.count(None) <= 5:
                # 将存放每行数据的列表追加到前面创建的空列表中
                list_data.append(row_list)
        else:
            return list_data


if __name__ == '__main__':
    dir_path = os.path.join(os.path.join(os.path.dirname(os.path.dirname(__file__)), "data_config"), "template")
    excel_path = os.path.join(dir_path, "APIAutoTest.xlsx")
    case_data_path = os.path.join(dir_path, "case_data.json")
    expect_data_path = os.path.join(dir_path, "expect_data.json")
    sql_data_path = os.path.join(dir_path, "sql_data.json")
    table_name = "BPM"
    excel = ReadExcel(excel_path, table_name, case_data_path, expect_data_path, sql_data_path)
    print(excel.get_data())
