'use strict';

var k8s = require('@kubernetes/client-node');

function _interopNamespaceCompat(e) {
  if (e && typeof e === 'object' && 'default' in e) return e;
  var n = Object.create(null);
  if (e) {
    Object.keys(e).forEach(function (k) {
      if (k !== 'default') {
        var d = Object.getOwnPropertyDescriptor(e, k);
        Object.defineProperty(n, k, d.get ? d : {
          enumerable: true,
          get: function () { return e[k]; }
        });
      }
    });
  }
  n.default = e;
  return Object.freeze(n);
}

var k8s__namespace = /*#__PURE__*/_interopNamespaceCompat(k8s);

class KuadrantK8sClient {
  kc;
  customApi;
  coreApi;
  constructor(config) {
    this.kc = new k8s__namespace.KubeConfig();
    const hasK8sConfig = config.has("kubernetes");
    if (hasK8sConfig) {
      const clusterLocatorMethods = config.getOptionalConfigArray("kubernetes.clusterLocatorMethods") || [];
      const configLocator = clusterLocatorMethods.find((c) => c.getString("type") === "config");
      if (configLocator) {
        const clusters = configLocator.getOptionalConfigArray("clusters") || [];
        if (clusters.length > 0) {
          const clusterConfig = clusters[0];
          const clusterName = clusterConfig.getString("name");
          const clusterUrl = clusterConfig.getString("url");
          const authProvider = clusterConfig.getOptionalString("authProvider");
          const skipTLSVerify = clusterConfig.getOptionalBoolean("skipTLSVerify") || false;
          if (authProvider === "serviceAccount") {
            const serviceAccountToken = clusterConfig.getString("serviceAccountToken");
            const cluster = {
              name: clusterName,
              server: clusterUrl,
              skipTLSVerify
            };
            const user = {
              name: `${clusterName}-service-account`,
              token: serviceAccountToken
            };
            const context = {
              name: `${clusterName}-context`,
              cluster: clusterName,
              user: user.name
            };
            this.kc.loadFromOptions({
              clusters: [cluster],
              users: [user],
              contexts: [context],
              currentContext: context.name
            });
            console.log(`k8s client initialised with explicit cluster config`);
            console.log(`  cluster: ${clusterName}`);
            console.log(`  url: ${clusterUrl}`);
            console.log(`  auth: serviceAccount`);
            console.log(`  skipTLSVerify: ${skipTLSVerify}`);
          } else {
            console.log(`unsupported authProvider: ${authProvider}, falling back to default`);
            this.kc.loadFromDefault();
          }
        } else {
          this.kc.loadFromDefault();
          this.logDefaultConfig("no clusters defined");
        }
      } else {
        this.kc.loadFromDefault();
        this.logDefaultConfig("no config locator found");
      }
    } else {
      this.kc.loadFromDefault();
      this.logDefaultConfig("no kubernetes config in app-config.yaml");
    }
    this.customApi = this.kc.makeApiClient(k8s__namespace.CustomObjectsApi);
    this.coreApi = this.kc.makeApiClient(k8s__namespace.CoreV1Api);
  }
  logDefaultConfig(reason) {
    console.log(`k8s client initialised using default config (${reason})`);
    const inClusterToken = process.env.KUBERNETES_SERVICE_HOST;
    if (inClusterToken) {
      console.log("  auth: in-cluster service account");
      console.log("  location: /var/run/secrets/kubernetes.io/serviceaccount/");
    } else {
      const kubeconfig = process.env.KUBECONFIG || "~/.kube/config";
      console.log("  auth: local kubeconfig");
      console.log(`  location: ${kubeconfig}`);
    }
  }
  async listCustomResources(group, version, plural, namespace) {
    try {
      const response = namespace ? await this.customApi.listNamespacedCustomObject(group, version, namespace, plural) : await this.customApi.listClusterCustomObject(group, version, plural);
      return response.body;
    } catch (error) {
      throw new Error(`failed to list ${plural}: ${error.message}`);
    }
  }
  async getCustomResource(group, version, namespace, plural, name) {
    try {
      const response = await this.customApi.getNamespacedCustomObject(
        group,
        version,
        namespace,
        plural,
        name
      );
      return response.body;
    } catch (error) {
      throw new Error(`failed to get ${plural}/${name}: ${error.message}`);
    }
  }
  async createSecret(namespace, secret) {
    try {
      const response = await this.coreApi.createNamespacedSecret(namespace, secret);
      return response.body;
    } catch (error) {
      throw new Error(`failed to create secret: ${error.message}`);
    }
  }
  async listSecrets(namespace) {
    try {
      const response = await this.coreApi.listNamespacedSecret(namespace);
      return { items: response.body.items || [] };
    } catch (error) {
      throw new Error(`failed to list secrets: ${error.message}`);
    }
  }
  async getSecret(namespace, name) {
    try {
      const response = await this.coreApi.readNamespacedSecret(name, namespace);
      return response.body;
    } catch (error) {
      throw new Error(`failed to get secret: ${error.message}`);
    }
  }
  async deleteSecret(namespace, name) {
    try {
      await this.coreApi.deleteNamespacedSecret(name, namespace);
    } catch (error) {
      throw new Error(`failed to delete secret: ${error.message}`);
    }
  }
  async createConfigMap(namespace, configMap) {
    try {
      const response = await this.coreApi.createNamespacedConfigMap(namespace, configMap);
      return response.body;
    } catch (error) {
      throw new Error(`failed to create configmap: ${error.message}`);
    }
  }
  async listConfigMaps(namespace, labelSelector) {
    try {
      const response = await this.coreApi.listNamespacedConfigMap(namespace, void 0, void 0, void 0, void 0, labelSelector);
      return { items: response.body.items || [] };
    } catch (error) {
      throw new Error(`failed to list configmaps: ${error.message}`);
    }
  }
  async getConfigMap(namespace, name) {
    try {
      const response = await this.coreApi.readNamespacedConfigMap(name, namespace);
      return response.body;
    } catch (error) {
      throw new Error(`failed to get configmap: ${error.message}`);
    }
  }
  async updateConfigMap(namespace, name, configMap) {
    try {
      const response = await this.coreApi.replaceNamespacedConfigMap(name, namespace, configMap);
      return response.body;
    } catch (error) {
      throw new Error(`failed to update configmap: ${error.message}`);
    }
  }
  async deleteConfigMap(namespace, name) {
    try {
      await this.coreApi.deleteNamespacedConfigMap(name, namespace);
    } catch (error) {
      throw new Error(`failed to delete configmap: ${error.message}`);
    }
  }
  async createCustomResource(group, version, namespace, plural, resource) {
    try {
      const response = await this.customApi.createNamespacedCustomObject(
        group,
        version,
        namespace,
        plural,
        resource
      );
      return response.body;
    } catch (error) {
      const statusCode = error.response?.statusCode || error.statusCode;
      const body = error.response?.body || error.body;
      const message = body?.message || error.message;
      const reason = body?.reason;
      const details = body?.details;
      console.error(`failed to create ${plural}:`, {
        statusCode,
        message,
        reason,
        details: JSON.stringify(details)
      });
      throw new Error(`failed to create ${plural}: ${message}${reason ? ` (${reason})` : ""}`);
    }
  }
  async deleteCustomResource(group, version, namespace, plural, name) {
    try {
      await this.customApi.deleteNamespacedCustomObject(
        group,
        version,
        namespace,
        plural,
        name
      );
    } catch (error) {
      throw new Error(`failed to delete ${plural}/${name}: ${error.message}`);
    }
  }
  async patchCustomResource(group, version, namespace, plural, name, patch) {
    try {
      const response = await this.customApi.patchNamespacedCustomObject(
        group,
        version,
        namespace,
        plural,
        name,
        patch,
        void 0,
        void 0,
        void 0,
        {
          headers: {
            "Content-Type": "application/merge-patch+json"
          }
        }
      );
      return response.body;
    } catch (error) {
      throw new Error(`failed to patch ${plural}/${name}: ${error.message}`);
    }
  }
  async patchCustomResourceStatus(group, version, namespace, plural, name, status) {
    try {
      const existing = await this.getCustomResource(group, version, namespace, plural, name);
      const updated = {
        ...existing,
        status
      };
      const response = await this.customApi.replaceNamespacedCustomObjectStatus(
        group,
        version,
        namespace,
        plural,
        name,
        updated
      );
      return response.body;
    } catch (error) {
      throw new Error(`failed to patch ${plural}/${name} status: ${error.message}`);
    }
  }
}

exports.KuadrantK8sClient = KuadrantK8sClient;
//# sourceMappingURL=k8s-client.cjs.js.map
