// SPDX-License-Identifier: Apache-2.0
import * as k8s from '@kubernetes/client-node';
import { SoloError } from '../../../core/errors/solo-error.js';
import { K8ClientClusters } from './resources/cluster/k8-client-clusters.js';
import { K8ClientConfigMaps } from './resources/config-map/k8-client-config-maps.js';
import { K8ClientContainers } from './resources/container/k8-client-containers.js';
import { K8ClientContexts } from './resources/context/k8-client-contexts.js';
import { K8ClientPods } from './resources/pod/k8-client-pods.js';
import { K8ClientServices } from './resources/service/k8-client-services.js';
import { K8ClientPvcs } from './resources/pvc/k8-client-pvcs.js';
import { K8ClientLeases } from './resources/lease/k8-client-leases.js';
import { K8ClientNamespaces } from './resources/namespace/k8-client-namespaces.js';
import { K8ClientIngressClasses } from './resources/ingress-class/k8-client-ingress-classes.js';
import { K8ClientSecrets } from './resources/secret/k8-client-secrets.js';
import { K8ClientIngresses } from './resources/ingress/k8-client-ingresses.js';
import { K8ClientCRDs } from './resources/crd/k8-clinet-crds.js';
import { KubeConfig } from '@kubernetes/client-node';
/**
 * A kubernetes API wrapper class providing custom functionalities required by solo
 *
 * Note: Take care if the same instance is used for parallel execution, as the behaviour may be unpredictable.
 * For parallel execution, create separate instances by invoking clone()
 */
export class K8Client {
    context;
    kubeConfig;
    kubeClient;
    coordinationApiClient;
    extensionApi;
    networkingApi;
    k8Leases;
    k8Clusters;
    k8ConfigMaps;
    k8Containers;
    k8Pods;
    k8Contexts;
    k8Services;
    k8Pvcs;
    k8Namespaces;
    k8IngressClasses;
    k8Secrets;
    k8Ingresses;
    k8CRDs;
    /**
     * Create a new k8Factory client for the given context, if context is undefined it will use the current context in kubeconfig
     * @param context - The context to create the k8Factory client for
     */
    constructor(context) {
        this.context = context;
        this.init(this.context);
    }
    // TODO make private, but first we need to require a cluster to be set and address the test cases using this
    init(context = undefined) {
        this.kubeConfig = this.getKubeConfig(context);
        if (!this.kubeConfig.getCurrentContext()) {
            throw new SoloError('No active kubernetes context found. ' + 'Please set current kubernetes context.');
        }
        if (!this.kubeConfig.getCurrentCluster()) {
            throw new SoloError('No active kubernetes cluster found. ' + 'Please create a cluster and set current context.');
        }
        this.kubeClient = this.kubeConfig.makeApiClient(k8s.CoreV1Api);
        this.networkingApi = this.kubeConfig.makeApiClient(k8s.NetworkingV1Api);
        this.coordinationApiClient = this.kubeConfig.makeApiClient(k8s.CoordinationV1Api);
        this.extensionApi = this.kubeConfig.makeApiClient(k8s.ApiextensionsV1Api);
        this.k8Clusters = new K8ClientClusters(this.kubeConfig);
        this.k8ConfigMaps = new K8ClientConfigMaps(this.kubeClient);
        this.k8Contexts = new K8ClientContexts(this.kubeConfig);
        this.k8Services = new K8ClientServices(this.kubeClient);
        this.k8Pods = new K8ClientPods(this.kubeClient, this.kubeConfig);
        this.k8Containers = new K8ClientContainers(this.kubeConfig, this.k8Pods);
        this.k8Pvcs = new K8ClientPvcs(this.kubeClient);
        this.k8Leases = new K8ClientLeases(this.coordinationApiClient);
        this.k8Namespaces = new K8ClientNamespaces(this.kubeClient);
        this.k8IngressClasses = new K8ClientIngressClasses(this.networkingApi);
        this.k8Secrets = new K8ClientSecrets(this.kubeClient);
        this.k8Ingresses = new K8ClientIngresses(this.networkingApi);
        this.k8CRDs = new K8ClientCRDs(this.extensionApi);
        return this;
    }
    getKubeConfig(context) {
        const kubeConfig = new KubeConfig();
        try {
            kubeConfig.loadFromDefault();
            if (context) {
                if (!kubeConfig.getContextObject(context)) {
                    throw new SoloError(`No kube config context found with name ${context}`);
                }
                kubeConfig.setCurrentContext(context);
            }
        }
        catch (error) {
            //* Try loading from cluster if loading from default fails
            try {
                kubeConfig.loadFromCluster();
            }
            catch (fromClusterError) {
                throw new SoloError('Failed to load Kubernetes configuration from cluster', fromClusterError, error);
            }
        }
        return kubeConfig;
    }
    namespaces() {
        return this.k8Namespaces;
    }
    clusters() {
        return this.k8Clusters;
    }
    configMaps() {
        return this.k8ConfigMaps;
    }
    containers() {
        return this.k8Containers;
    }
    contexts() {
        return this.k8Contexts;
    }
    services() {
        return this.k8Services;
    }
    pods() {
        return this.k8Pods;
    }
    pvcs() {
        return this.k8Pvcs;
    }
    leases() {
        return this.k8Leases;
    }
    secrets() {
        return this.k8Secrets;
    }
    ingressClasses() {
        return this.k8IngressClasses;
    }
    ingresses() {
        return this.k8Ingresses;
    }
    crds() {
        return this.k8CRDs;
    }
}
//# sourceMappingURL=k8-client.js.map