/*
 * Copyright (c) 2018, 2026, Oracle and/or its affiliates.
 * Licensed under The Universal Permissive License (UPL), Version 1.0
 * as shown at https://oss.oracle.com/licenses/upl/
 */
const Utils=require("../jetwc-lib/jetwcutils-componentAuditUtils");const ruleDef=function(){};ruleDef.prototype.getName=function(){return"jetwc-required-subproperty"};ruleDef.prototype.getShortDescription=function(){return"Checks for the required attribute setting on component sub-properties"};ruleDef.prototype.getDescription=function(){return"This rule checks that for complex properties (those with sub-properties) we do not have have a situation where the sub-property is defined as required. As a best practice, any required inputs to a component should really be top level properties."};ruleDef.prototype.register=function(context){return{compjson:this._doAudit}};ruleDef.prototype._doAudit=function(context){if(context.suppData.obj){let issue;const meta=context.suppData.obj;const fullName=Utils.getComponentFullName(meta);const componentType=Utils.getComponentType(meta);if(componentType==="composite"&&meta.properties){const expandedProperties=[];this._propertyDrill(context,meta,expandedProperties);expandedProperties.forEach(prop=>{if(prop.defaultCount>0){issue=new context.Issue(`Component ${fullName}, nested property ${prop.propertyPath} has the required attribute set.  Best practice dictates that only top-level properties should be marked as required.`);context.reporter.addIssue(issue,context)}})}}};ruleDef.prototype._propertyDrill=function(context,metadata,accumulator,parentInfo){const levelPath=parentInfo?parentInfo.propertyPath+".":"";const defaultCount=parentInfo?parentInfo.defaultCount:0;const propKeys=Object.keys(metadata.properties);propKeys.forEach(propertyName=>{const propertyMeta=metadata.properties[propertyName];if(!this._shouldIgnore(propertyMeta)){let runningCount=defaultCount;if(propertyMeta.hasOwnProperty("required")&&propertyMeta.required&&parentInfo){runningCount++}const propertyInfo={propertyPath:levelPath+propertyName,defaultCount:runningCount};if(propertyMeta.hasOwnProperty("properties")){this._propertyDrill(context,propertyMeta,accumulator,propertyInfo)}accumulator.push(propertyInfo)}})};ruleDef.prototype._shouldIgnore=function(metadataNode){if(metadataNode&&metadataNode.extension&&metadataNode.extension.audit&&metadataNode.extension.audit.ignore&&Array.isArray(metadataNode.extension.audit.ignore)&&metadataNode.extension.audit.ignore.includes(this.getName())){return true}return false};module.exports=ruleDef;