/**
* Copyright Super iPaaS Integration LLC, an IBM Company 2024
*/
import {CollectionCreator} from '../../src/newman/newman-collection.builder.js';
import {GatewayAssetHandler} from '../../src/converter/gateway-asset.handler.js';
import {RefParser} from '../../src/parsers/ref.parser.js';
import AdmZip from 'adm-zip';
jest.mock('../../src/converter/gateway-asset.handler.ts');
jest.mock('../../src/parsers/ref.parser');
jest.mock('../../src/index');
jest.mock('adm-zip');
jest.mock('../../src/service/log-wrapper.ts');

describe('CollectionCreator', () => {
	let collectionCreator: CollectionCreator;
	let buffer: Buffer;
	let parsedData: any;

	beforeEach(() => {
		collectionCreator = new CollectionCreator();
		buffer = Buffer.from('test buffer');
		parsedData = {
			metadata: { name: 'TestCollection' },
			spec: {
				api: { $ref: 'PaymentAPI:1.0.1' },
				request: [{
					method: 'GET',
					resource: '/test',
					headers: [{ key: 'Content-Type', value: 'application/json' }],
					auth: { noauth: true },
					assertions: {},
					settings: { sslVerification: false, encodeURL: true }
				}],
				environment: { $ref: 'default:TestEnvironment:1.0.0' }
			}
		};

		(RefParser as jest.Mock).mockImplementation(() => {
			return {
				parseRef: jest.fn().mockReturnValue({
					namespace: 'default',
					name: 'TestEnvironment',
					version: '1.0.0'
				})
			};
		});

		(GatewayAssetHandler as jest.Mock).mockImplementation(() => {
			return {
				getApiEndpoints: jest.fn().mockReturnValue(['http://example.com'])
			};
		});

		(AdmZip as jest.Mock).mockImplementation(() => {
			return {
				getEntries: jest.fn().mockReturnValue([
					{
						getData: jest.fn().mockReturnValue(Buffer.from(`
kind: environment
metadata:
  name: TestEnvironment
  version: 1.0.0
  namespace: default
spec:
  variables:
    - key: content-type
      value: application/json
                    `))
					}
				])
			};
		});
	});

	afterEach(() => {
		jest.clearAllMocks();
	});

	// it('should call initializeCollection and getApiEndpoints when createCollection is called', async () => {
	// 	const gatewayAssetHandlerMock = new GatewayAssetHandler(buffer) as jest.Mocked<GatewayAssetHandler>;
	// 	gatewayAssetHandlerMock.getApiEndpoints.mockResolvedValue(['http://example.com']);
	// 	const initializeCollectionSpy = jest.spyOn(collectionCreator as any, 'initializeCollection');
	// 	const getApiEndpointsSpy = jest.spyOn(collectionCreator as any, 'getApiEndpoints').mockResolvedValue(['http://example.com']);
	// 	await collectionCreator.createCollection(parsedData, buffer);
	// 	expect(initializeCollectionSpy).toHaveBeenCalledWith('TestCollection');
	// 	expect(getApiEndpointsSpy).toHaveBeenCalledWith(buffer, 'PaymentAPI:1.0.1');
	// });

	// it('should replace placeholders and construct items correctly', async () => {
	// 	const gatewayAssetHandlerMock = new GatewayAssetHandler(buffer) as jest.Mocked<GatewayAssetHandler>;
	// 	gatewayAssetHandlerMock.getApiEndpoints.mockResolvedValue(['http://example.com']);
	//
	// 	const mockCollection = {
	// 		info: { name: 'TestCollection Collection', version: '1.0.0', schema: 'https://schema.getpostman.com/json/collection/v2.1.0/collection.json' },
	// 		item: []
	// 	};
	// 	jest.spyOn(collectionCreator as any, 'initializeCollection').mockResolvedValue(mockCollection);
	// 	jest.spyOn(collectionCreator as any, 'getApiEndpoints').mockResolvedValue(['http://example.com']);
	// 	jest.spyOn(collectionCreator as any, 'getReplacedItems').mockReturnValue(parsedData.spec.request);
	//
	// 	const collection = await collectionCreator.createCollection(parsedData, buffer);
	// 	expect(collection.item.length).toBeGreaterThan(0);
	// 	const firstItem = collection.item[0] as any;
	// 	expect(firstItem.request.method).toBe('GET');
	// 	expect(firstItem.request.header[0].key).toBe('Content-Type');
	// 	expect(firstItem.request.header[0].value).toBe('application/json');
	// });

	it('should construct a valid request item', async() => {
		const requestItem = {
			method: 'POST',
			resource: '/test',
			headers: [{ key: 'Content-Type', value: 'application/json' }],
			auth: { noauth: true },
			payload: {
				raw: {
					json: '{"key": "value"}'
				}
			},
			assertions: {},
			settings: { sslVerification: false, encodeURL: true }
		};

		const constructedItem = await (collectionCreator as any).constructItem(requestItem, buffer);

		expect(constructedItem.request.method).toBe('POST');
		expect(constructedItem.request.header[0].key).toBe('Content-Type');
		expect(constructedItem.request.header[0].value).toBe('application/json');
		expect(constructedItem.request.body.raw).toBe('{"key": "value"}');
	});

	it('should replace placeholders in request items with environment variables', () => {
		const requestItem = {
			method: 'POST',
			resource: '/test',
			headers: [{ key: 'Content-Type', value: '${content-type}' }],
			auth: { noauth: true },
			payload: {
				raw: {
					json: '{"key": "value"}'
				}
			},
			assertions: {},
			settings: { sslVerification: false, encodeURL: true }
		};

		const variables = [{ key: 'content-type', value: 'application/json' }];
		const replacedItem = (collectionCreator as any).replacePlaceholders(requestItem, variables);

		expect(replacedItem.headers[0].value).toBe('application/json');
	});

	it('should construct assertions correctly', async() => {
		const assertions = {
			expressions: [
				{ name: 'Validate response code', key: 'code', value: 200, action: 'equals' }
			]
		};

		const constructedAssertions = await (collectionCreator as any).constructAssertion(assertions, buffer);

		expect(constructedAssertions.length).toBe(1);
		expect(constructedAssertions[0].listen).toBe('test');
		expect(constructedAssertions[0].script.exec.length).toBeGreaterThan(1);
		expect(constructedAssertions[0].script.exec[1]).toContain('pm.test(\'Validate response code\', function () { pm.expect(pm.response.code).to.equals(200); });');
	});
});