/**
* Copyright Super iPaaS Integration LLC, an IBM Company 2024
*/
import { KindEnums } from '@apic/api-model/common/StudioEnums.js';
import { checkForNullOrUndefined, equalsIgnoreCase, isNullOrUndefined } from '../../common/data-helper.js';
import { BaseAsset } from '@apic/studio-client-model';
import { getSubDirectory } from '../../common/fs-helper.js';
import { searchAsset } from '../build-helper.js';
import { showError } from '../../common/message-helper.js';
import { AssetCache } from '../../../cache/asset-cache.js';
import { COMMA, APIM_MODE } from '../../../constants/app-constants.js';
import { getOtherProjectsNames } from '../root-dir-helper.js';
 enum Kinds{
	DataPowerAssembly='DataPowerAssembly',
	FreeFlowPolicySequence='FreeFlowPolicySequence',
	StagedPolicySequence='StagedPolicySequence',
    API = "API"
}

const isPolicyKind = (kind: string | null | undefined): boolean => {
	if (typeof kind !== 'string') {
		return false;
	}

	const policyKinds: string[] = [
		KindEnums.Log,
		KindEnums.ErrorProcessing,
		KindEnums.IdentifyAndAuthorize,
		KindEnums.SetContextVariable,
		KindEnums.MonitorTraffic,
		KindEnums.CacheServiceResult,
		KindEnums.RateLimiter,
		KindEnums.InvokeAWSLambdaFunction,
		KindEnums.DataMasking,
		KindEnums.HTTPInvoke,
		KindEnums.InvokeMessagingExtension,
		KindEnums.TransformRequest,
		KindEnums.TransformResponse,
		KindEnums.ValidateAPISpecification,
		KindEnums.Route,
		KindEnums.Transport,
		KindEnums.OutboundAlias,
		KindEnums.OutboundAnonymous,
		KindEnums.OutboundBasicAuth,
		KindEnums.OutboundIncomingJWT,
		KindEnums.OutboundKerberosAuth,
		KindEnums.OutboundNTLMAuth,
		KindEnums.OutboundOAuth2,
		KindEnums.Scope,
		KindEnums.WebMethodsISService,
		KindEnums.CustomHttpHeader,
		KindEnums.InboundBulkHead,
        KindEnums.AuthorizeUser,
		KindEnums.SetMediaType,
		"Invoke"
	];

	return policyKinds.some((policyKind) => equalsIgnoreCase(policyKind, kind));
};

const isProjectBelongsToDataPower=(assets:BaseAsset[]) => {
  if (isNullOrUndefined(assets)) {
    return false;
  }
  for (const asset of assets) {
    if (Kinds.DataPowerAssembly.toString()===asset.kind) {
      return true;
    }
  }
  return false;
};

const isProjectBelongsToDataPowerNanoGw=(assets:BaseAsset[]) => {
  if (isNullOrUndefined(assets)) {
    return false;
  }
  for (const asset of assets) {
    if (Kinds.FreeFlowPolicySequence.toString()===asset.kind) {
      return true;
    }
  }
  return false;
};


const findPolicyKind= (apiAsset:any):string =>{
	
	const projectNames=AssetCache.getInstance().getProjectNames();
	
	let currentProjects = new Set<string>(projectNames.split(COMMA));
	
	const rootDirPath=AssetCache.getInstance().getRootDirPath();
	
	const otherProjects: Set<string> | null = getOtherProjectsNames(
    rootDirPath,
    projectNames
  );
  
  // Combine current projects with other projects (if any)
  const allProjects = otherProjects !== null
    ? new Set<string>([...currentProjects, ...otherProjects])
    : currentProjects;
  
   for (const project of allProjects) {
      const projectDirPath = getSubDirectory(rootDirPath, project);
      let spec = checkForNullOrUndefined(
      apiAsset.spec,
      `Spec is not defined for the asset with kind 'API' and name '${apiAsset.metadata?.name}'`
    );
     const policySeq: any = spec["policy-sequence"];
  if(!policySeq || policySeq.length === 0){
       showError('No policy-sequence is defined');
       return '';
  }
     if(searchAsset(Kinds.DataPowerAssembly,policySeq[0].$ref, projectDirPath)){
      return Kinds.DataPowerAssembly.toString();
     }else if(searchAsset(Kinds.FreeFlowPolicySequence,policySeq[0].$ref, projectDirPath)){
      return Kinds.FreeFlowPolicySequence.toString();
     }else if(searchAsset(Kinds.StagedPolicySequence,policySeq[0].$ref, projectDirPath)) {
       return Kinds.StagedPolicySequence.toString();
     }
   }
   return '';
}



export { isPolicyKind, isProjectBelongsToDataPower, isProjectBelongsToDataPowerNanoGw, findPolicyKind, Kinds };
