// Importing necessary modules and functions for the test
import createKubernetesApplyManifestAction from './k8s-apply';
import { KubernetesObjectApi } from '@kubernetes/client-node';
import { TemplateAction } from '@backstage/plugin-scaffolder-backend';
import { JsonObject } from '@backstage/config';
import * as yaml from 'js-yaml';
import fs from 'fs';

// Mocking the external dependencies
jest.mock('fs');
jest.mock('@kubernetes/client-node', () => {
	const original = jest.requireActual('@kubernetes/client-node');
	return {
		...original,
		KubernetesObjectApi: {
			makeApiClient: jest.fn().mockReturnValue({
				create: jest.fn().mockResolvedValue({}),
			}),
		},
	};
});
jest.mock('js-yaml');

// Mocking the fs module to not directly read from the file system in tests
jest.mock('fs', () => ({
	readFileSync: jest.fn().mockImplementation(() => 'mocked file content'),
}));

// Defining the structure of the ActionContext for type checking
type ActionContext = {
	input: {
		manifestPath: string;
	};
	logger: {
		info: jest.Mock<any, any>;
		error: jest.Mock<any, any>;
	};
	logStream: {
		write: jest.Mock<any, any>;
	};
	workspacePath: string;
	output: (name: string, value: any) => void;
	createTemporaryDirectory: () => Promise<string>;
};

describe('createKubernetesApplyManifestAction', () => {
	let action: TemplateAction<JsonObject>;

	// Preparing the action before running tests
	beforeAll(() => {
		action = createKubernetesApplyManifestAction();
	});

	it('successfully applies a Kubernetes manifest from file, using environment variables for configuration', async () => {
		// Asserting that environment variables are defined
		expect(process.env.TOKEN).toBeDefined();
		expect(process.env.CLUSTER_URL).toBeDefined();

		// Creating a mock context matching the ActionContext structure
		const mockContext: ActionContext = {
			input: {
				manifestPath: './manifests/ns.yaml',
			},
			logger: {
				info: jest.fn(),
				error: jest.fn(),
			},
			logStream: {
				write: jest.fn(),
			},
			workspacePath: '/tmp',
			output: jest.fn(),
			createTemporaryDirectory: jest
				.fn()
				.mockResolvedValue('/tmp/mock-temp-dir'),
		};

		// Running the handler with the mocked context
		await action.handler(mockContext);

		// Verifying that the Kubernetes client API was called
		expect(KubernetesObjectApi.makeApiClient).toHaveBeenCalled();

		// Example assertion to check if logging occurred as expected
		expect(mockContext.logger.info).toHaveBeenCalled();
	});

	// Here you can add more tests as needed
});
