// SPDX-License-Identifier: Apache-2.0
import { expect } from 'chai';
import { before, describe, it, after } from 'mocha';
import { DefaultKindClientBuilder } from '../../../../../src/integration/kind/impl/default-kind-client-builder.js';
import { ClusterCreateOptionsBuilder } from '../../../../../src/integration/kind/model/create-cluster/create-cluster-options-builder.js';
import { KindCluster } from '../../../../../src/integration/kind/model/kind-cluster.js';
import { KindDependencyManager } from '../../../../../src/core/dependency-managers/index.js';
import { container } from 'tsyringe-neo';
import fs from 'node:fs';
import path from 'node:path';
import * as os from 'node:os';
import { resetForTest } from '../../../../test-container.js';
import { Duration } from '../../../../../src/core/time/duration.js';
import { exec } from 'node:child_process';
import { promisify } from 'node:util';
const execAsync = promisify(exec);
describe('KindClient Integration Tests', function () {
    this.timeout(Duration.ofMinutes(1).toMillis());
    let kindClient;
    let kindPath;
    const testClusterName = 'test-kind-client';
    const temporaryDirectory = fs.mkdtempSync(path.join(os.tmpdir(), 'kind-test-'));
    let originalKubeConfigContext = null;
    before(async () => {
        resetForTest();
        // Save original kubectl context if it exists
        try {
            const { stdout } = await execAsync('kubectl config current-context');
            originalKubeConfigContext = stdout.trim();
            console.log(`Saved original kubectl context: ${originalKubeConfigContext}`);
        }
        catch {
            console.log('No kubectl context found or kubectl not available');
            originalKubeConfigContext = null;
        }
        // Download and install Kind
        const kindManager = container.resolve(KindDependencyManager);
        await kindManager.install(temporaryDirectory);
        kindPath = kindManager.getExecutablePath();
        console.log(`Using Kind at: ${kindPath}`);
        // Create Kind client
        const clientBuilder = new DefaultKindClientBuilder();
        kindClient = await clientBuilder.executable(kindPath).build();
    });
    after(async () => {
        if (kindClient) {
            try {
                // Clean up test cluster if it exists
                const clusters = await kindClient.getClusters();
                if (clusters.some((cluster) => cluster.name === testClusterName)) {
                    console.log(`Deleting test cluster: ${testClusterName}`);
                    await kindClient.deleteCluster(testClusterName);
                }
            }
            catch (error) {
                console.error('Error during cleanup:', error);
            }
        }
        // Restore original kubectl context if it existed
        if (originalKubeConfigContext) {
            try {
                console.log(`Restoring original kubectl context: ${originalKubeConfigContext}`);
                await execAsync(`kubectl config use-context ${originalKubeConfigContext}`);
            }
            catch (error) {
                console.error('Error restoring kubectl context:', error);
            }
        }
        // Clean up temp directory
        try {
            fs.rmSync(temporaryDirectory, { recursive: true, force: true });
        }
        catch (error) {
            console.error('Error cleaning up temp directory:', error);
        }
    });
    it('should get Kind version', async () => {
        const version = await kindClient.version();
        expect(version).to.not.be.undefined;
        expect(version.major).to.be.a('number');
        expect(version.minor).to.be.a('number');
        expect(version.patch).to.be.a('number');
        console.log(`Kind version: ${version.toString()}`);
    });
    it('should create a cluster', async () => {
        const options = ClusterCreateOptionsBuilder.builder().build();
        const response = await kindClient.createCluster(testClusterName, options);
        expect(response).to.not.be.undefined;
        expect(response.name).to.equal(testClusterName);
    });
    it('should list clusters', async () => {
        const clusters = await kindClient.getClusters();
        expect(clusters).to.be.an('array');
        expect(clusters.length).to.be.greaterThan(0);
        const testCluster = clusters.find(c => c.name === testClusterName);
        expect(testCluster).to.not.be.undefined;
        expect(testCluster).to.be.instanceOf(KindCluster);
        expect(testCluster.name).to.equal(testClusterName);
    });
    it('should get cluster nodes', async () => {
        const response = await kindClient.getNodes(testClusterName);
        expect(response).to.not.be.undefined;
        expect(response.nodes).to.be.an('array');
        expect(response.nodes.length).to.be.greaterThan(0);
        // Verify node naming pattern (should have the cluster name in it)
        const nodes = response.nodes;
        for (const node of nodes) {
            expect(node).to.include(testClusterName);
        }
    });
    it('should get kubeconfig', async () => {
        const response = await kindClient.getKubeConfig(testClusterName);
        expect(response).to.not.be.undefined;
        expect(response.config).to.exist;
        expect(response.config.apiVersion).to.eq('v1');
        expect(response.config.clusters).to.exist;
        expect(response.config.clusters.length).to.be.greaterThan(0);
        expect(response.config.contexts).to.exist;
    });
    it('should export kubeconfig', async () => {
        const response = await kindClient.exportKubeConfig(testClusterName);
        expect(response).to.not.be.undefined;
        expect(response.kubeConfigContext).to.be.a('string');
    });
    it('should export logs', async () => {
        const response = await kindClient.exportLogs(testClusterName);
        expect(response).to.not.be.undefined;
        expect(response.exportPath).to.be.a('string');
        // Verify logs directory exists
        const logsExist = fs.existsSync(response.exportPath);
        expect(logsExist).to.be.true;
    });
    it('should delete a cluster', async () => {
        const response = await kindClient.deleteCluster(testClusterName);
        expect(response).to.not.be.undefined;
        // Verify cluster was deleted
        const clusters = await kindClient.getClusters();
        const deletedCluster = clusters.find((c) => c.name === testClusterName);
        expect(deletedCluster).to.be.undefined;
    });
});
//# sourceMappingURL=kind-client.test.js.map