/*
 * 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 path=require("path");const Utils=require("../jetwc-lib/jetwcutils-componentAuditUtils");const ruleDef=function(){};ruleDef.prototype.getName=function(){return"jetwc-nls-languages"};ruleDef.prototype.getShortDescription=function(){return"Ensures that the correct language bundles are supplied"};ruleDef.prototype.getDescription=function(){return"This rule ensures that a string bundle both declares and implements locale overrides for each required language"};ruleDef.prototype.register=function(context){return{CallExpression:this._doAudit,TSExportAssignment:this._doAudit}};ruleDef.prototype._doAudit=function(context,node){let issue;const NT=context.utils.AstUtils.getNodeTypes();if(context.filepath.includes("/resources/nls/")){const dirPath=path.dirname(context.filepath);const bundleName=path.basename(context.filepath);const pathSegs=dirPath.split("/").reverse();const ruleOptions=context.rulePack.getRuleCustomOptions();if(pathSegs[0]==="nls"){const withinComponent=Utils.matchComponentPath(context,dirPath);if(withinComponent){let langProps;if(node.callee&&node.callee.type===NT.IDENTIFIER&&node.callee.name==="define"&&node.arguments&&node.arguments.length>0&&node.arguments[0].type===NT.OBJ_EXPR){langProps=node.arguments[0].properties}else if(node.type===NT.EXPORT_ASSIGNMENT&&node.expression&&node.expression.type===NT.OBJ_EXPR){langProps=node.expression.properties}if(langProps){const languagesSupported=langProps.reduce((langs,langEntry)=>{if(langEntry.type===NT.PROPERTY&&langEntry.key.type===NT.LITERAL){if(langEntry.value.type===NT.LITERAL){langs.push({locale:langEntry.key.value,verified:false,enabled:langEntry.value.value})}else if(langEntry.value.type===NT.OBJ_EXPR){langs.push({locale:langEntry.key.value,verified:true})}}return langs},[]);const nlsFiles=context.utils.fsUtils.readDir(dirPath);const expectedLocales=ruleOptions.locales.reduce((locs,locale)=>{if(locale.includes("|")){const alternatives=locale.split("|");locs.push({locale:alternatives[0].toLowerCase(),alt:alternatives[1].toLowerCase(),found:false,configured:locale})}else{locs.push({locale:locale.toLowerCase(),alt:locale.toLowerCase(),found:false,configured:locale})}return locs},[]);expectedLocales.push({locale:"root",alt:"root",found:false,configured:"Root Bundle"});languagesSupported.forEach(lang=>{if(lang.verified){issue=new context.Issue(`Component '${withinComponent}' - the recommended pattern for string bundles is for each locale to be defined in its own file in a locale specific subdirectory under /resources/nls/`);issue.setMsgKey(context.ruleName+"_1");context.reporter.addIssue(issue,context,"info")}else{if(!lang.enabled){issue=new context.Issue(`Component '${withinComponent}' - locale support declared for '${lang.locale}', but is currently disabled`);issue.setMsgKey(context.ruleName+"_2");context.reporter.addIssue(issue,context,"info")}else{let bundleFound=false;const localeFolder=nlsFiles.filter(nlsChild=>{let found=false;if(!nlsChild.isFile){found=this._localeMatch(nlsChild.name,lang.locale,ruleOptions.strict)}return found});if(localeFolder.length===1){const localeSpecificFile=localeFolder[0].files.filter(localeChild=>localeChild.isFile&&localeChild.name===bundleName);if(localeSpecificFile.length===1){bundleFound=true;expectedLocales.forEach(localeRec=>{if(this._localeMatch(localeRec.locale,lang.locale,ruleOptions.strict)||this._localeMatch(localeRec.alt,lang.locale,ruleOptions.strict)){localeRec.found=true}})}}if(!bundleFound){issue=new context.Issue(`Component '${withinComponent}' - locale support declared for '${lang.locale}', but the expected file: '/resources/nls/${lang.locale}/${bundleName}' is missing`);issue.setMsgKey(context.ruleName+"_3");context.reporter.addIssue(issue,context)}}}});if(!issue){expectedLocales.forEach(localeRec=>{if(!localeRec.found){issue=new context.Issue(`Component '${withinComponent}' - required locale support not provided for '${localeRec.configured}'`);issue.setMsgKey(context.ruleName+"_4");context.reporter.addIssue(issue,context)}})}}}}}};ruleDef.prototype._localeMatch=function(test,against,strict){let l1,l2;if(strict){l1=test;l2=against}else{l1=test.toLowerCase().replace("_","-");l2=against.toLowerCase().replace("_","-")}return l1===l2};module.exports=ruleDef;