#!/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.

import schema_utils as su
from uri_constraint_checker import UriConstraintChecker
from rspbody_constraint_checker import RspBodyConstraintChecker
from reqbody_constraint_checker import ReqBodyConstraintChecker


class ConstraintChecker:
    def __init__(self, target_json, target_path, schema_dir):
        self.rscs = target_json['Resources']
        self.target_path = target_path
        self.schema_dir = schema_dir

    def check(self):
        cons_success = False
        # 遍历Resources下的Uri/Interfaces
        for i in range(len(self.rscs)):
            # 非对外接口，不需要检查
            ucc = UriConstraintChecker(self.target_path, self.schema_dir)
            uri = self.rscs[i]['Uri']
            if 'ActionInfo' in uri or '/Actions/' in uri:
                continue
            intfs = self.rscs[i]['Interfaces']
            if not ucc.is_extern_intf(uri):
                continue
            # 校验Uri定义完整性
            # 校验资源方法有效性
            ucc.check(uri, intfs)
            odata_type = ucc.get_odata_type()
            if odata_type is None:
                cons_success = False
                continue
            rsc_name, prop_name = su.get_schema_from_odata_type(odata_type)
            for intf in intfs:
                if 'RspBody' in intf:
                    # 校验GET请求的required约束
                    # 校验属性定义的完整性
                    rspcc = RspBodyConstraintChecker(self.target_path, uri, self.schema_dir,
                                                     rsc_name, prop_name, intf['Type'])
                    cons_success = rspcc.check(intf['RspBody']) and cons_success
                elif 'ReqBody' in intf:
                    # 校验POST请求的requiredOnCreate约束
                    # 校验资源方法请求体的additionalProperties约束
                    # 校验PATCH请求的readonly约束
                    # 校验资源属性类型定义的一致性
                    reqcc = ReqBodyConstraintChecker(self.target_path, uri, self.schema_dir,
                                                     rsc_name, prop_name, intf['Type'])
                    cons_success = reqcc.check(intf['ReqBody']) and cons_success
        return cons_success