# -*- coding: UTF-8 -*-
"""
@Project ：pytest_src 
@File    ：ModuleCfgCheck.py
@Author  ：haojiang
@Date    ：2022/9/23 9:02 
"""
import logging

from Base.Arxml import Arxml
from Base.CfgCheckBase import CfgCheckBase
from lxml import etree
import os
from typing import List

class ModuleCfgCheck(CfgCheckBase):
    def __init__(self, module_name: str, project_path: str):
        super().__init__()
        self.module_name = module_name
        self.project_path = project_path
        self.registered_check_items = dict()
        self.load_arxml()


    def load_arxml(self):
        arxml_name = ''
        configure_files = list()
        for iter_dirPath, dirs, files in os.walk(self.project_path):
            configure_files = files.copy()
            break

        for file in configure_files:
            if f'{self.module_name}_ecuc' in file:
                arxml_name = os.path.join(self.project_path, file)

        if arxml_name != '':
            self.arxml_root = Arxml(arxml_name).root

    def register_param_check_item(self, check_ID: int, check_items: List):
        '''

        :param check_ID:
        :param check_items: [(item_name1, value1), (item_name2, value2), ...]
        :return:
        '''

        current_id_items = self.registered_check_items.get(check_ID, [])
        current_id_items.extend(check_items) # extend 实现原地拓展，返回值为None，所以不能将返回值作为拓展后的结果
        self.registered_check_items[check_ID] = current_id_items

    def do_all_param_check(self):
        for check_ID, check_items in self.registered_check_items.items():
            logging.info(f'Checking Item ID {check_ID}:')
            self.do_param_check(check_items)

    def do_param_check(self, check_items: List, search_pattern=None, get_match_element_function=None) -> bool:
        match_res = False
        for param_name, param_expect_value in check_items:
            cfg_check = CfgCheckBase()
            if get_match_element_function != None:
                match_element = get_match_element_function(check_items, **search_pattern)
            else:
                match_element = self.arxml_root
            match_res = cfg_check.parameter_match(match_element, param_name, param_expect_value)

        return match_res

    def get_detail_element(self, check_items, xpath_str, xpath_text='', xpath_rule=None):
        ret = None
        param_name, expect_value = check_items[0]

        match_element = Arxml.get_all_match_element(self.arxml_root, xpath_str, xpath_text, xpath_rule)
        if match_element is None:
            logging.error(f'By Pattern {xpath_str}-{xpath_text}-{xpath_rule}, not find valud element!')
            ret = None
        else:
            for elem in match_element:

                parent_elem = Arxml.get_parent_element(elem)
                match_string = etree.tostring(parent_elem).decode()
                if param_name in match_string:
                    ret = parent_elem
                    logging.info(f'Find Valid Element: {match_string}')
                    break
                else:
                    logging.info(match_string)
        return ret


def check_module_param_check(project: str, module_name: str, check_item: tuple, search_pattern=None) -> bool:
    mcc = ModuleCfgCheck(module_name, project)
    if search_pattern != None:
        costum_func = mcc.get_detail_element
    else:
        costum_func = None
    cmp_result = mcc.do_param_check([check_item], search_pattern, costum_func)

    return cmp_result


if __name__ == '__main__':
    logging.basicConfig(level=logging.INFO)
    # mcc = ModuleCfgCheck('Dem', r'D:\01_Work\02_WP\EP39_EREV\branch\src\Config\ECUC')
    # mcc.register_param_check_item(0, [('DemClearDTCBehavior', 'DEM_CLRRESP_V1OLATILE')])
    # mcc.register_param_check_item(1, [('DemClearDTCBehavior', 'DEM_CLRRESP_V1OLATILE')])
    # mcc.register_param_check_item(2, [('DemClearDTCBehavior', 'DEM_CLRRESP_V1OLATILE')])
    # mcc.register_param_check_item(3, [('DemClearDTCBehavior', 'DEM_CLRRESP_V1OLATILE')])
    # mcc.register_param_check_item(4, [('DemMaxNumberEventEntryPrimary', '40')])
    # mcc.register_param_check_item(5, [('DemImmediateNvStorage', 'true')])

    mcc = ModuleCfgCheck('CanTp', r'D:\01_Work\02_WP\EP39_EREV\branch\src\Config\ECUC')
    mcc.register_param_check_item(0, [('CanTpChannelMode', 'CANTP_MODE_FULL_DUPLEX')])
    mcc.register_param_check_item(0, [('CanTpMainFunctionPeriod', '0.006')])


    mcc.do_all_param_check()