import { AppConstants } from '../constants/app.constants.js';
import yaml from 'js-yaml';
import {
	UpperCaseKinds,
	YamlContent,
	Api_Spec_Ref,
	Policy_Spec_Ref,
	PolicySequence_Spec_Ref,
	Scope_Spec_Ref,
	Transport_Spec_Ref,
	Routing_Spec_Ref,
	SetContextVariable_Spec_Ref,
	IAM_Spec_Ref,
	OutboundAlias_Spec_Ref,
	OutboundBasicAuth_Spec_Ref,
	OutboundKerberosAuth_Spec_Ref,
	OutboundNTLMAuth_Spec_Ref,
	OutboundOAuth2_Spec_Ref,
	DataMasking_Spec_Ref,
	WebMethodsISService_Spec_Ref,
	AuthorizeUser_Spec_Ref,
	InboundBulkHead_Spec_Ref,
	InboundMessaging_Spec_Ref,
	MessageConfig_Spec_Ref,
	Tuple_Spec_Ref,
	CustomHttpHeader_Spec_Ref,
	SetMediaType_Spec_Ref
} from '../model/interface.js';
import { KindEnums } from '@apic/api-model/common/StudioEnums.js';
import { LogWrapper } from './log-wrapper.js';
import { Package_Spec } from '@apic/api-model/package/Package.js';
import { Plan_Spec_Ref, RequestLimit_Spec_Ref } from '@apic/studio-client-model';
/**
 * AssetValidator class is responsible to check the basic structure validations for the asset yamls of studio.
 */
export class AssetValidator {

	public validateAssets(genObj: YamlContent): boolean {
		const kind = genObj.kind.toUpperCase();
		if (!UpperCaseKinds.includes(kind)) {
			LogWrapper.logError('0255', `Unidentified kind: ${genObj.kind}`);
			return false;
		}
		LogWrapper.logInfo('0256', `${genObj.kind}`);
		switch (kind) {
			case KindEnums.API.toUpperCase():
				return this.validateApi(genObj);
			case KindEnums.PolicySequence.toUpperCase():
				return this.validatePolicySequence(genObj);
			case KindEnums.GlobalPolicy.toUpperCase():
				return this.validateGlobalPolicy(genObj);
			case KindEnums.Scope.toUpperCase():
				return this.validateScope(genObj);
			case KindEnums.Transport.toUpperCase():
				return this.validateTransport(genObj);
			case KindEnums.Route.toUpperCase():
				return this.validateRoute(genObj);
			case KindEnums.SetContextVariable.toUpperCase():
				return this.validateSetContextVariable(genObj);
			case KindEnums.IdentifyAndAuthorize.toUpperCase():
				return this.validateIdentifyAndAuthorize(genObj);
			case KindEnums.DataMasking.toUpperCase():
				return this.validateDataMasking(genObj);
			case KindEnums.WebMethodsISService.toUpperCase():
				return this.validateWebMethodsISService(genObj);
			case KindEnums.OutboundAlias.toUpperCase():
				return this.validateOutboundAlias(genObj);
			case KindEnums.OutboundAnonymous.toUpperCase():
				return true;
			case KindEnums.OutboundBasicAuth.toUpperCase():
				return this.validateOutboundBasicAuth(genObj);
			case KindEnums.OutboundIncomingJWT.toUpperCase():
				return true;
			case KindEnums.OutboundKerberosAuth.toUpperCase():
				return this.validateOutboundKerberosAuth(genObj);
			case KindEnums.OutboundNTLMAuth.toUpperCase():
				return this.validateOutboundNTLMAuth(genObj);
			case KindEnums.OutboundOAuth2.toUpperCase():
				return this.validateOutboundOAuth2(genObj);
			case KindEnums.AuthorizeUser.toUpperCase():
				return this.validateAuthorizeUser(genObj);
			case KindEnums.InboundBulkHead.toUpperCase():
				return this.validateInboundBulkHead(genObj);
			case KindEnums.InboundMessaging.toUpperCase():
				return this.validateInboundMessaging(genObj);
			case KindEnums.MessageConfig.toUpperCase():
				return this.validateMessageConfig(genObj);
			case KindEnums.Tuple.toUpperCase():
				return this.validateTuple(genObj);
			case KindEnums.CustomHttpHeader.toUpperCase():
				return this.validateCustomHttpHeader(genObj);
			case KindEnums.SetMediaType.toUpperCase():
				return this.validateSetMediaType(genObj);
			case KindEnums.Plan.toUpperCase():
				return this.validatePlan(genObj);
			case KindEnums.Package.toUpperCase():
				return this.validatePackage(genObj);
			case KindEnums.RequestLimit.toUpperCase():
				return this.validateRequestLimit(genObj);
			// case KindEnums.Test.toUpperCase():
			// 	return true;
			// case KindEnums.HTTPEndpoint.toUpperCase():
			// 	return true;
			// case KindEnums.Environment.toUpperCase():
			// 	return true;
			default:
				LogWrapper.logWarn('0255', `Unimplemented kind: ${kind}`);
				return true;   // This to be updated to false once all the kinds are incorporated in studio application.

		}
	}

	private validateApi(genObj: YamlContent): boolean {
		const specObj = JSON.stringify(genObj.spec);
		const apiSpec = yaml.load(specObj) as Api_Spec_Ref;
		let valid = true;
		const policySequence = AppConstants.POLICY_SEQ as keyof typeof apiSpec;
		if (apiSpec?.['api-spec'] == null || apiSpec?.[policySequence] == null) {
			LogWrapper.logDebug('0003', 'kind API must have api specification some policies');
			LogWrapper.logError('0257', `${genObj.kind}`);
			valid = false;
		}
		LogWrapper.logInfo('0258', `${genObj.kind}`);
		return valid;
	}

	private validateTuple(genObj: YamlContent): boolean {
		const specObj = JSON.stringify(genObj.spec);
		const tupleSpec = yaml.load(specObj) as Tuple_Spec_Ref;
		let valid = true;
		if (tupleSpec?.['value'] == null) {
			LogWrapper.logError('0257', `${genObj.kind}`);
			valid = false;
		}
		LogWrapper.logInfo('0258', `${genObj.kind}`);
		return valid;
	}
	private validatePolicySequence(genObj: YamlContent): boolean {
		const specObj = JSON.stringify(genObj.spec);
		const policySequenceSpec = yaml.load(specObj) as PolicySequence_Spec_Ref;
		let valid = true;
		// if (policySequenceSpec?.routing == null || policySequenceSpec?.transport == null) {
		// 	LogWrapper.logError('0257', `${genObj.kind}`);
		// 	valid = false;
		// }
		LogWrapper.logInfo('0258', `${genObj.kind}`);
		return valid;
	}

	private validateGlobalPolicy(genObj: YamlContent): boolean {
		const specObj = JSON.stringify(genObj.spec);
		const policySpec = yaml.load(specObj) as Policy_Spec_Ref;
		let valid = true;
		const policySequence = AppConstants.POLICY_SEQ as keyof typeof policySpec;
		if (policySpec?.[policySequence] == null && policySpec?.['filter-attributes'] == null) {
			LogWrapper.logError('0257', `${genObj.kind}`);
			valid = false;
		}
		LogWrapper.logInfo('0258', `${genObj.kind}`);
		return valid;
	}

	private validateScope(genObj: YamlContent): boolean {
		const specObj = JSON.stringify(genObj.spec);
		const scopeSpec = yaml.load(specObj) as Scope_Spec_Ref;
		let valid = true;
		if (scopeSpec?.resources == null) {
			LogWrapper.logError('0257', `${genObj.kind}`);
			LogWrapper.logDebug('0003', 'Scope must have atleast one resource');
			valid = false;
		} else {
			for (const resource of scopeSpec.resources) {
				if (resource.path == null) {
					LogWrapper.logError('0257', `${genObj.kind}`);
					LogWrapper.logDebug('0003', 'Resource has no path defined.');
					valid = false;
				}
			}
		}
		LogWrapper.logInfo('0258', `${genObj.kind}`);
		return valid;
	}

	private validateTransport(genObj: YamlContent): boolean {
		const specObj = JSON.stringify(genObj.spec);
		const tranSpec = yaml.load(specObj) as Transport_Spec_Ref;
		let valid = true;
		if (tranSpec?.protocol == null) {
			LogWrapper.logError('0257', `${genObj.kind}`);
			valid = false;
		}
		LogWrapper.logInfo('0258', `${genObj.kind}`);
		return valid;
	}

	private validateSetMediaType(genObj: YamlContent): boolean {
		const specObj = JSON.stringify(genObj.spec);
		const tranSpec = yaml.load(specObj) as SetMediaType_Spec_Ref;
		let valid = true;
		if (tranSpec?.defaultContentType == null || tranSpec?.defaultAcceptHeader == null) {
			LogWrapper.logError('0257', `${genObj.kind}`);
			valid = false;
		}
		LogWrapper.logInfo('0258', `${genObj.kind}`);
		return valid;
	}

	private validatePlan(genObj: YamlContent): boolean {
		const specObj = JSON.stringify(genObj.spec);
		const planSpec = yaml.load(specObj) as Plan_Spec_Ref;
		let valid = true;
		if (planSpec?.qos == null) {
			LogWrapper.logError('0257', `${genObj.kind}`);
			valid = false;
		}
		LogWrapper.logInfo('0258', `${genObj.kind}`);
		return valid;
	}

	private validatePackage(genObj: YamlContent): boolean {
		const specObj = JSON.stringify(genObj.spec);
		const packageSpec = yaml.load(specObj) as Package_Spec;
		let valid = true;
		if (packageSpec?.apis == null || packageSpec?.plans == null) {
			LogWrapper.logError('0257', `${genObj.kind}`);
			valid = false;
		}
		LogWrapper.logInfo('0258', `${genObj.kind}`);
		return valid;
	}

	private validateRequestLimit(genObj: YamlContent): boolean {
		const specObj = JSON.stringify(genObj.spec);
		const requestLimitSpec = yaml.load(specObj) as RequestLimit_Spec_Ref;
		let valid = true;
		if (requestLimitSpec?.maxRequest == null || requestLimitSpec?.interval == null) {
			LogWrapper.logError('0257', `${genObj.kind}`);
			valid = false;
		}
		LogWrapper.logInfo('0258', `${genObj.kind}`);
		return valid;
	}

	private validateRoute(genObj: YamlContent): boolean {
		const specObj = JSON.stringify(genObj.spec);
		const routeSpec = yaml.load(specObj) as Routing_Spec_Ref;
		let valid = true;

		const invalidEndpoints = Object.keys(routeSpec ?? {}).filter(key => !AppConstants.ALLOWED_ENDPOINTS.includes(key));

		if (routeSpec == null || invalidEndpoints.length > 0) {
			LogWrapper.logError('0257', `${genObj.kind}`);
			valid = false;
		}

		LogWrapper.logInfo('0258', `${genObj.kind}`);
		return valid;
	}

	private validateCustomHttpHeader(genObj: YamlContent): boolean {
		const specObj = JSON.stringify(genObj.spec);
		const headerSpec = yaml.load(specObj) as CustomHttpHeader_Spec_Ref;
		let valid = true;
		if (headerSpec?.property == null) {
			LogWrapper.logError('0257', `${genObj.kind}`);
			LogWrapper.logDebug('0003', 'CustomHttpHeader must have atleast one property');
			valid = false;
		} else {
			for (const prop of headerSpec.property) {
				if (prop.key == null) {
					LogWrapper.logError('0257', `${genObj.kind}`);
					LogWrapper.logDebug('0003', 'Property has no key defined.');
					valid = false;
				}
				if (prop.value == null) {
					LogWrapper.logError('0257', `${genObj.kind}`);
					LogWrapper.logDebug('0003', 'Property has no value defined.');
					valid = false;
				}
			}
		}
		LogWrapper.logInfo('0258', `${genObj.kind}`);
		return valid;
	}

	private validateSetContextVariable(genObj: YamlContent): boolean {
		const specObj = JSON.stringify(genObj.spec);
		const setContextVariableSpec = yaml.load(specObj) as SetContextVariable_Spec_Ref;
		let valid = true;
		if (setContextVariableSpec.condition == null) {
			LogWrapper.logError('0257', `${genObj.kind}`);
			LogWrapper.logDebug('0003', `Kind: ${genObj.kind} must have atleast one condition`);
			valid = false;
		} else if (setContextVariableSpec.variable !== undefined) {
			for (const variable of setContextVariableSpec.variable) {
				if (variable.name == null) {
					LogWrapper.logDebug('0003', `Kind: ${genObj.kind} Context variable must have a name`);
					LogWrapper.logError('0257', `${genObj.kind}`);
					valid = false;
				}
			}
		}
		LogWrapper.logInfo('0258', `${genObj.kind}`);
		return valid;
	}

	private validateIdentifyAndAuthorize(genObj: YamlContent): boolean {
		const specObj = JSON.stringify(genObj.spec);
		const IAMSpec = yaml.load(specObj) as IAM_Spec_Ref;
		if (IAMSpec.identificationType === undefined) {
			LogWrapper.logError('0257', `${genObj.kind}`);
			LogWrapper.logDebug('0003', `Kind: ${genObj.kind} must have 'identificationType' specified.`);
			return false;
		}
		if (IAMSpec.identificationType === null) {
			LogWrapper.logError('0257', `${genObj.kind}`);
			LogWrapper.logDebug('0003', `Kind: ${genObj.kind} must have at least one of 'or' or 'and' specified under identificationType.`);
			return false;
		}
		const hasOr = IAMSpec.identificationType.or;
		const hasAnd = IAMSpec.identificationType.and;
		if (hasOr !== undefined && hasAnd !== undefined) {
			LogWrapper.logError('0257', `${genObj.kind}`);
			LogWrapper.logDebug('0003', `Kind: ${genObj.kind} cannot have both 'or' and 'and' specified under identificationType.`);
			return false;
		}
		if (hasOr !== undefined) {
			if (hasOr === null) {
				LogWrapper.logError('0257', `${genObj.kind}`);
				LogWrapper.logDebug('0003', `Kind: ${genObj.kind} 'or' under identificationType must have at least one key-value pair.`);
				return false;
			}
		}
		if (hasAnd !== undefined) {
			if (hasAnd === null) {
				LogWrapper.logError('0257', `${genObj.kind}`);
				LogWrapper.logDebug('0003', `Kind: ${genObj.kind} 'and' under identificationType must have at least one key-value pair.`);
				return false;
			}
		}

		LogWrapper.logInfo('0258', `${genObj.kind}`);
		return true;
	}

	private validateDataMasking(genObj: YamlContent): boolean {
		const specObj = JSON.stringify(genObj.spec);
		const DataMaskingSpec = yaml.load(specObj) as DataMasking_Spec_Ref;
		let valid = true;
		if (DataMaskingSpec.transformations == null) {
			LogWrapper.logError('0257', `${genObj.kind}`);
			valid = false;
		}
		LogWrapper.logInfo('0258', `${genObj.kind}`);
		return valid;
	}

	private validateWebMethodsISService(genObj: YamlContent): boolean {
		const specObj = JSON.stringify(genObj.spec);
		const WebMethodsISServiceSpec = yaml.load(specObj) as WebMethodsISService_Spec_Ref;
		let valid = true;
		if (WebMethodsISServiceSpec.services !== undefined) {
			for (const service of WebMethodsISServiceSpec.services) {
				if (service.name == null) {
					LogWrapper.logDebug('0003', `Kind: ${genObj.kind} Service must have a name`);
					LogWrapper.logError('0257', `${genObj.kind}`);
					valid = false;
				}
			}
		}
		LogWrapper.logInfo('0258', `${genObj.kind}`);
		return valid;
	}
	private validateOutboundAlias(genObj: YamlContent): boolean {
		const specObj = JSON.stringify(genObj.spec);
		const OutboundAliasSpec = yaml.load(specObj) as OutboundAlias_Spec_Ref;
		let valid = true;
		return valid;
	}

	private validateOutboundBasicAuth(genObj: YamlContent): boolean {
		const specObj = JSON.stringify(genObj.spec);
		const OutboundBasicAuthSpec = yaml.load(specObj) as OutboundBasicAuth_Spec_Ref;
		let valid = true;
		if (OutboundBasicAuthSpec.use_incoming_credentials === undefined && OutboundBasicAuthSpec.use_custom_credentials === undefined) {
			LogWrapper.logDebug('0003', `Kind: ${genObj.kind} must have useIncomingCredentials or useCustomCredentials`);
			LogWrapper.logError('0257', `${genObj.kind}`);
			valid = false;
		}
		else if (OutboundBasicAuthSpec.use_custom_credentials !== null) {
			if (OutboundBasicAuthSpec.use_custom_credentials?.username === null || OutboundBasicAuthSpec.use_custom_credentials?.password === null) {
				LogWrapper.logDebug('0003', `Kind: ${genObj.kind} useCustomCredentials must have username and password`);
				LogWrapper.logError('0257', `${genObj.kind}`);
				valid = false;
			}
		}
		return valid;
	}

	private validateOutboundKerberosAuth(genObj: YamlContent): boolean {
		const specObj = JSON.stringify(genObj.spec);
		const OutboundKerberosAuthSpec = yaml.load(specObj) as OutboundKerberosAuth_Spec_Ref;
		let valid = true;
		if (OutboundKerberosAuthSpec.use_incoming_http_credentials !== undefined) {
			valid = valid && this.validateKerberosUseIncomingHttpCredentials(OutboundKerberosAuthSpec, genObj);
		} else if (OutboundKerberosAuthSpec.use_delegate_incoming_credentials !== undefined) {
			valid = valid && this.validateKerberosUseDelegateIncomingCredentials(OutboundKerberosAuthSpec, genObj);
		} else if (OutboundKerberosAuthSpec.use_custom_credentials !== undefined) {
			valid = valid && this.validateKerberosUseCustomCredentials(OutboundKerberosAuthSpec, genObj);
		}
		return valid;
	}
	getNoOfKerberosAuthMethods(OutboundKerberosAuthSpec: OutboundKerberosAuth_Spec_Ref): number {
		let count = 0;
		if (OutboundKerberosAuthSpec.use_incoming_http_credentials !== undefined) {
			count += 1;
		}
		if (OutboundKerberosAuthSpec.use_custom_credentials !== undefined) {
			count += 1;
		}
		if (OutboundKerberosAuthSpec.use_delegate_incoming_credentials !== undefined) {
			count += 1;
		}
		if (OutboundKerberosAuthSpec.use_incoming_kerbose_credentials !== undefined) {
			count += 1;
		}
		return count;
	}

	validateKerberosUseCustomCredentials(OutboundKerberosAuthSpec: OutboundKerberosAuth_Spec_Ref, genObj: YamlContent): boolean {
		if (OutboundKerberosAuthSpec.use_custom_credentials.client_principal === null ||
			OutboundKerberosAuthSpec.use_custom_credentials.client_password === null ||
			OutboundKerberosAuthSpec.use_custom_credentials.service_principal === null ||
			OutboundKerberosAuthSpec.use_custom_credentials.service_principal_nameform === null) {
			LogWrapper.logDebug('0003', `Kind: ${genObj.kind} useCustomCredentials must have clientPrincipal, clientPassword
				servicePrincipal and servicePrincipalNameFrom`);
			LogWrapper.logError('0257', `${genObj.kind}`);
			return false;
		}
		return true;
	}
	validateKerberosUseDelegateIncomingCredentials(OutboundKerberosAuthSpec: OutboundKerberosAuth_Spec_Ref, genObj: YamlContent): boolean {
		if (OutboundKerberosAuthSpec.use_delegate_incoming_credentials.client_principal === null ||
			OutboundKerberosAuthSpec.use_delegate_incoming_credentials.client_password === null ||
			OutboundKerberosAuthSpec.use_delegate_incoming_credentials.service_principal === null ||
			OutboundKerberosAuthSpec.use_delegate_incoming_credentials.service_principal_nameform === null) {
			LogWrapper.logDebug('0003', `Kind: ${genObj.kind} useDelegateIncomingCredentials must have clientPrincipal, clientPassword
				servicePrincipal and servicePrincipalNameFrom`);
			LogWrapper.logError('0257', `${genObj.kind}`);
			return false;
		}
		return true;
	}
	validateKerberosUseIncomingHttpCredentials(OutboundKerberosAuthSpec: OutboundKerberosAuth_Spec_Ref, genObj: YamlContent) {
		if (OutboundKerberosAuthSpec.use_incoming_http_credentials.service_principal === null ||
			OutboundKerberosAuthSpec.use_incoming_http_credentials.service_principal_nameform === null
		) {
			LogWrapper.logDebug('0003', `Kind: ${genObj.kind} useIncomingHttpCredentials must have
					servicePrincipal and servicePrincipalNameFrom`);
			LogWrapper.logError('0257', `${genObj.kind}`);
			return false;
		}
		return true;
	}
	private validateOutboundNTLMAuth(genObj: YamlContent): boolean {
		const specObj = JSON.stringify(genObj.spec);
		const OutboundNTLMAuthSpec = yaml.load(specObj) as OutboundNTLMAuth_Spec_Ref;
		let valid = true;
		if (OutboundNTLMAuthSpec.use_custom_credentials === undefined &&
			OutboundNTLMAuthSpec.use_incoming_http_credentials === undefined &&
			OutboundNTLMAuthSpec.use_transparent_auth === undefined) {
			LogWrapper.logDebug('0003', `Kind: ${genObj.kind} must have useIncomingHttpCredentials or useCustomCredentials or useTransparentAuth`);
			LogWrapper.logError('0257', `${genObj.kind}`);
			valid = false;
		}
		return valid;
	}

	private validateOutboundOAuth2(genObj: YamlContent): boolean {
		const specObj = JSON.stringify(genObj.spec);
		const OutboundOAuth2Spec = yaml.load(specObj) as OutboundOAuth2_Spec_Ref;
		let valid = true;
		if (OutboundOAuth2Spec.use_incoming_oauth_token === undefined && OutboundOAuth2Spec.use_custom_credentials === undefined) {
			LogWrapper.logDebug('0003', `Kind: ${genObj.kind} must have useIncomingOauthToken or useCustomCredentials`);
			LogWrapper.logError('0257', `${genObj.kind}`);
			valid = false;
		}
		else if (OutboundOAuth2Spec.use_custom_credentials !== null) {
			if (OutboundOAuth2Spec.use_custom_credentials?.token === null) {
				LogWrapper.logDebug('0003', `Kind: ${genObj.kind} useCustomCredentials must have OAuth Token defined`);
				LogWrapper.logError('0257', `${genObj.kind}`);
				valid = false;
			}
		}
		return valid;
	}

	private validateAuthorizeUser(genObj: YamlContent): boolean {
		const specObj = JSON.stringify(genObj.spec);
		const AuthorizeUserSpec = yaml.load(specObj) as AuthorizeUser_Spec_Ref;
		let valid = true;
		if (AuthorizeUserSpec.users === undefined && AuthorizeUserSpec.teams === undefined && AuthorizeUserSpec.groups === undefined) {
			LogWrapper.logError('0257', `${genObj.kind}`);
			valid = false;
		}
		LogWrapper.logInfo('0258', `${genObj.kind}`);
		return valid;
	}

	private validateInboundBulkHead(genObj: YamlContent): boolean {
		const specObj = JSON.stringify(genObj.spec);
		const InboundBulkHeadSpec = yaml.load(specObj) as InboundBulkHead_Spec_Ref;
		let valid = true;
		if (InboundBulkHeadSpec.maxConcurrentCalls == null) {
			LogWrapper.logDebug('0003', `Kind: ${genObj.kind} must have maxConcurrentCalls defined`);
			LogWrapper.logError('0257', `${genObj.kind}`);
			valid = false;
		}
		if (InboundBulkHeadSpec.enableBulkheadForCallbacks !== null) {
			if (InboundBulkHeadSpec.enableBulkheadForCallbacks?.maxConcurrentCallbacks === null) {
				LogWrapper.logDebug('0003', `Kind: ${genObj.kind} enableBulkheadForCallbacks must have maxConcurrentCallbacks defined`);
				LogWrapper.logError('0257', `${genObj.kind}`);
				valid = false;
			}
		}
		if (InboundBulkHeadSpec.retryAfterResponseHeader !== null) {
			if (InboundBulkHeadSpec.retryAfterResponseHeader?.retryAfterValue === null) {
				LogWrapper.logDebug('0003', `Kind: ${genObj.kind} retryAfterResponseHeader must have retryAfterValue defined`);
				LogWrapper.logError('0257', `${genObj.kind}`);
				valid = false;
			}
		}
		LogWrapper.logInfo('0258', `${genObj.kind}`);
		return valid;
	}

	private validateInboundMessaging(genObj: YamlContent): boolean {
		const specObj = JSON.stringify(genObj.spec);
		const InboundMessagingSpec = yaml.load(specObj) as InboundMessaging_Spec_Ref;
		let valid = true;
		if (InboundMessagingSpec.alias === undefined) {
			LogWrapper.logDebug('0003', `Kind: ${genObj.kind} must have connection alias defined`);
			LogWrapper.logError('0257', `${genObj.kind}`);
			valid = false;
		}
		if (InboundMessagingSpec.source === null) {
			LogWrapper.logDebug('0003', `Kind: ${genObj.kind} must have source defined`);
			LogWrapper.logError('0257', `${genObj.kind}`);
			valid = false;
		}
		else {
			for (const source of InboundMessagingSpec.source) {
				if (source.name == null || source.resource == null || source.type == null) {
					LogWrapper.logDebug('0003', `Kind: ${genObj.kind} Source must have a name, type and resource`);
					LogWrapper.logError('0257', `${genObj.kind}`);
					valid = false;
				}
			}
		}
		LogWrapper.logInfo('0258', `${genObj.kind}`);
		return valid;
	}

	private validateMessageConfig(genObj: YamlContent): boolean {
		const specObj = JSON.stringify(genObj.spec);
		const MessageConfigSpec = yaml.load(specObj) as MessageConfig_Spec_Ref;
		let valid = true;
		if (MessageConfigSpec.connectionAlias == null || MessageConfigSpec.destination.name == null ||
			MessageConfigSpec.destination.type == null || MessageConfigSpec.deliveryMode == null || MessageConfigSpec.replyTo.type == null ||
			MessageConfigSpec.ttl == null || MessageConfigSpec.timeToWait == null) {
			LogWrapper.logDebug('0003', `Kind: ${genObj.kind} must have connection Alias, destination name, destination type, replyTo type, ttl, timeToWait and deliveryMode`);
			LogWrapper.logError('0257', `${genObj.kind}`);
			valid = false;
		}
		LogWrapper.logInfo('0258', `${genObj.kind}`);
		return valid;
	}

}

