import https from 'https';
import { URL } from 'url';

function validateUrl(url: string): void {
	try {
		new URL(url);
	} catch (error) {
		throw new Error(`${url} is an invalid URL`);
	}
}

function defaults<T extends Record<string, any>>(
	target: T,
	source: Partial<T>
): T {
	Object.keys(source).forEach((key) => {
		const sourceValue = source[key as keyof T];
		if (sourceValue !== undefined) {
			target[key as keyof T] = sourceValue as T[keyof T];
		}
	});
	return target;
}

export default class K8sApi {
	private token: string;
	private clusterUrl: URL;
	private skipTLSVerify: boolean;
	private caData?: string;

	constructor(
		clusterUrl: string,
		token: string,
		skipTLSVerify: boolean = false,
		caData?: string
	) {
		validateUrl(clusterUrl);
		this.token = token;
		this.clusterUrl = new URL(clusterUrl);
		this.skipTLSVerify = skipTLSVerify;
		this.caData = caData;
	}

	// Basic implementation of applyObject - modify as needed
	async applyObject(k8sObject: any): Promise<any> {
		// Implementation of the method goes here
	}

	async request(
		path: string,
		options?: https.RequestOptions,
		body?: string
	): Promise<any> {
		const defaultOptions: https.RequestOptions = {
			hostname: this.clusterUrl.hostname,
			port: this.clusterUrl.port || '6443',
			path: path,
			method: 'GET',
			headers: {},
			rejectUnauthorized: !this.skipTLSVerify,
			ca: this.caData,
		};

		const finalOptions = defaults(options || {}, defaultOptions);

		defaults(finalOptions.headers as Record<string, any>, {
			Authorization: `Bearer ${this.token}`,
		});

		return new Promise((fulfill, reject) => {
			const req = https.request(finalOptions, (res) => {
				let data = '';
				res.on('data', (chunk) => (data += chunk.toString()));
				res.on('end', () => {
					try {
						fulfill({ statusCode: res.statusCode, data: JSON.parse(data) });
					} catch (error) {
						if (error instanceof Error) {
							reject(new Error(`Failed to parse response: ${error.message}`));
						} else {
							reject(new Error('Failed to parse response'));
						}
					}
				});
			});
			req.on('error', (error) => {
				if (error instanceof Error) {
					reject(new Error(`HTTP request failed: ${error.message}`));
				} else {
					reject(new Error('HTTP request failed'));
				}
			});
			if (body) {
				req.write(body);
			}
			req.end();
		});
	}
}
