/**
* Copyright Super iPaaS Integration LLC, an IBM Company 2024
*/
/* eslint-disable @typescript-eslint/no-explicit-any */
import {GatewaysJson} from '@apic/studio-shared';
import {Gateway, processDeployment} from '@apic/studio-deploy';
import {showError, showInfo, showSuccess} from '../../helpers/common/message-helper.js';
import {readFileAsBuffer} from '../../helpers/common/fs-helper.js';
import {ALL, NONE} from '../../constants/app-constants.js';
import {
	DEPLOYING_PROJECTS,
	DEPLOYMENT_SUCCESS,
	DEPLOYMENT_FAILURE,
	LINE,
	DEPLOY_STARTED, DEPLOYMENT_FAILURE_SOME_ASSET,
	APIENDPOINTS, DETAILED_INFO
} from '../../constants/message-constants.js';
import {GatewayResponses} from '../../model/studio/gateway-response-model.js';
import Table from 'cli-table3';
import {DebugManager} from '../../debug/debug-manager.js';
import { GatewayResponseAPI } from '../../model/studio/deploy-response-model.js';
import {setGatewayEndpoint} from '../../configure/endpoints/config.js';

export const prepareGatewayJson = (target: string, username: string, password: string, overwrite: boolean, is_mcsp_enabled: boolean): GatewaysJson => {
	target=safeExtractOrigin(target);
	const gateways: Gateway[] = [{
		gatewayURL: target,
		gatewayUser: username,
		gatewaySecret: password,
		is_mcsp_enabled: is_mcsp_enabled
	}];

	return {
		gateways,
		overwrite: overwrite ? ALL : NONE,
		skip: overwrite ? NONE : ALL
	};
};

const safeExtractOrigin = (url: string): string => {
    try {
      return new URL(url).origin; // Extracts "https://example.com"
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
    } catch (error) {
      return url;
    }
  };

export const prepareArchiveBuffer = (archivePath: string) : Buffer => {
	return readFileAsBuffer(archivePath);
};
export const executeDeployment = async (gatewayJson: GatewaysJson, fileBuffer: Buffer) => {
	showInfo(LINE);
	showInfo(DEPLOY_STARTED);
	showInfo(LINE);
	const responses = await processDeployment(gatewayJson, fileBuffer);

	if (DebugManager.getInstance().isDebugEnabled()) {
		showInfo(DEPLOYING_PROJECTS);
		showInfo(DETAILED_INFO);
		showInfo(JSON.stringify(responses, null, 2));
	}

	await deploymentStatus(responses);

	// Process and set the gateway endpoints
	const gatewayResponses = await prepareResponse(responses);

	await setGatewayEndpoint(gatewayResponses);
	return gatewayResponses;

};

const deploymentStatus = async (responses: GatewayResponses) =>{
	let allSuccess = true;
	for(const response of responses) {
		if (response.success) {
			if (response && 'data' in response && response.data) {
				const studioResults = response.data.StudioResult;
				studioResults.forEach((item: any) => {
					if (item.API) {
						showInfo(`Deployment ${item.API.status} - ${item.API.namespace}:${item.API.assetName}:${item.API.version}`);
						if (item.API.status !== 'Success') {
							allSuccess = false;
						}
					} else if (item.Policy) {
						showInfo(`Deployment ${item.Policy.status} - ${item.Policy.namespace}:${item.Policy.assetName}:${item.Policy.version}`);
						if (item.Policy.status !== 'Success') {
							allSuccess = false;
						}
					}
				}
				);
			}
		}
		else{
			showError(DEPLOYMENT_FAILURE);
			if ('message' in response) {
				showError(response.message);
			}
			allSuccess=false;
		}
	}
	if(allSuccess){
		showSuccess(DEPLOYMENT_SUCCESS);
	}
	else{
		showError(DEPLOYMENT_FAILURE_SOME_ASSET);
		process.exit(1);
	}
};

const filterAPIsfromStudioResults = async (response: { success: boolean; statusCode: any; data: any; }) => {
	const studioResults = response.data.StudioResult;
	const studioResultsAPIs = studioResults.filter((studioResult: any) => {
		return ('API' in studioResult);
	});
	return studioResultsAPIs;
};

const prepareResponse = async (responses: GatewayResponses): Promise< GatewayResponseAPI[]> => {
	const gatewayResponses:  GatewayResponseAPI[] = [];

	for (const response of responses) {
		if (response.success) {
			showSuccess(APIENDPOINTS);

			const successTable = new Table({
				head: ['APIs', 'Gateway Endpoints'],
				style: {
					head: ['blue'],
					border: ['yellow'],
				}
			});

			if ('data' in response && response.data) {
				const studioResultsAPIs = await filterAPIsfromStudioResults(response);
				studioResultsAPIs.forEach((api: any) => {
					const apiData: GatewayResponseAPI = {
						name: api.API.name,
						gatewayEndpoints: api.API.gatewayEndpoints,
						kind: api.API.kind,
						namespace: api.API.namespace,
						version: api.API.version,
						assetName: api.API.assetName,
					};
					const endpoints = apiData.gatewayEndpoints.filter(endpoint => endpoint !== undefined).join('\n');
					successTable.push([apiData.name, endpoints]);
					gatewayResponses.push(apiData);
				});
				console.log(successTable.toString());
			}
		}
	}

	return 	gatewayResponses;
};


