#!/usr/bin/env python
# coding: utf-8
# Copyright (c) 2024 Huawei Technologies Co., Ltd.
# openUBMC is licensed under Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
#         http://license.coscl.org.cn/MulanPSL2
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
# See the Mulan PSL v2 for more details.

from jsonschema import Draft202012Validator
import schema_utils as su


class SyntaxChecker:
    def __init__(self, schema_json, target_json, filename, path):
        self.schema_json = schema_json
        self.target_json = target_json
        self.filename = filename
        self.path = path
        self.errorlog_path = su.get_abspath_under_rackmount(su.ERRORLOG_PATH)
        self.is_success = True

    def print_syntax_error(self, value):
        self.is_success = False
        su.ep.print_errorlog('1-2',
                             'None',
                             self.path,
                             value,
                             'None',
                             'None',
                             'None',
                             'None',
                             'None')

    def check_oem_ref(self, oem_value):
        if not isinstance(oem_value, dict):
            return
        if '$ref' in oem_value:
            if oem_value['$ref'].startswith('#'):
                self.print_syntax_error(oem_value['$ref'])
        elif 'type' in oem_value:
            if oem_value['type'] != 'null':
                self.print_syntax_error(oem_value['type'])
        elif 'anyOf' in oem_value:
            for item in oem_value['anyOf']:
                self.check_oem_ref(item)
        else:
            self.print_syntax_error('None')
        return

    def check_part_oem_def(self, schema):
        if isinstance(schema, dict):
            for key, value in schema.items():
                if key == 'Oem':
                    self.check_oem_ref(value)
                elif isinstance(value, (dict, list)):
                    self.check_part_oem_def(value)
        elif isinstance(schema, list):
            for item in schema:
                self.check_part_oem_def(item)
        return

    def check(self):
        v = Draft202012Validator(self.schema_json)
        errors = sorted(v.iter_errors(self.target_json), key=lambda e: e.path)
        if errors:
            errorlog_file = open(self.errorlog_path, 'a+')
            print('=============syntax errors found in file:', self.path, file=errorlog_file)
            for error in errors:
                print('[Rule 1-1]: Schema语法检查失败, 详细信息如下=============', file=errorlog_file)
                print('错误信息: ', error.message, file=errorlog_file)
                print('语法要求: ', error.validator_value, file=errorlog_file)
                print('错误位置: ', error.json_path, file=errorlog_file)
                print('错误内容: ', error.instance, file=errorlog_file)
            errorlog_file.close()
            print('=============syntax errors found in file:', self.path)
            for error in errors:
                print('[Rule 1-1]: Schema语法检查失败, 详细信息如下=============')
                print('错误信息: ', error.message)
                print('语法要求: ', error.validator_value)
                print('错误位置: ', error.json_path)
                print('错误内容: ', error.instance)
            return False
        
        # 'hw'全部自定义文件和'huawei_'开头的部分自定义文件跳过检查
        if self.filename.startswith('hw') or self.filename.startswith('huawei_'):
            return True
        self.check_part_oem_def(self.target_json)
        return self.is_success