'use strict';

var k8sClient = require('../k8s-client.cjs.js');

class APIProductEntityProvider {
  k8sClient;
  connection;
  providerId = "kuadrant-apiproduct-provider";
  constructor(config) {
    console.log("apiproduct provider: constructor called");
    this.k8sClient = new k8sClient.KuadrantK8sClient(config);
  }
  getProviderName() {
    return this.providerId;
  }
  async connect(connection) {
    console.log("apiproduct provider: connect called");
    this.connection = connection;
    console.log("apiproduct provider: starting initial sync");
    await this.refresh();
    console.log("apiproduct provider: scheduling periodic refresh every 30 seconds");
    setInterval(async () => {
      await this.refresh();
    }, 30 * 1e3);
  }
  async refresh() {
    console.log("apiproduct provider: refresh called");
    if (!this.connection) {
      console.log("apiproduct provider: no connection, skipping refresh");
      return;
    }
    try {
      console.log("apiproduct provider: fetching apiproducts from kubernetes");
      const response = await this.k8sClient.listCustomResources(
        "devportal.kuadrant.io",
        "v1alpha1",
        "apiproducts"
      );
      const apiProducts = response.items || [];
      console.log(`apiproduct provider: found ${apiProducts.length} apiproducts`);
      const publishedProducts = apiProducts.filter((product) => {
        const publishStatus = product.spec.publishStatus || "Draft";
        return publishStatus === "Published";
      });
      console.log(`apiproduct provider: filtered to ${publishedProducts.length} published apiproducts (${apiProducts.length - publishedProducts.length} drafts excluded)`);
      const entities = publishedProducts.map((product) => this.transformToEntity(product)).filter((entity) => entity !== null);
      console.log(`apiproduct provider: transformed ${entities.length} entities`);
      console.log("apiproduct provider: submitting entities to catalog");
      await this.connection.applyMutation({
        type: "full",
        entities: entities.map((entity) => ({
          entity,
          locationKey: `kuadrant-apiproduct:${entity.metadata.namespace}/${entity.metadata.name}`
        }))
      });
      console.log(`apiproduct provider: synced ${entities.length} api products`);
    } catch (error) {
      console.error("error refreshing apiproduct entities:", error);
    }
  }
  transformToEntity(product) {
    const namespace = product.metadata.namespace || "default";
    const name = product.metadata.name;
    const displayName = product.spec.displayName || name;
    const description = product.spec.description || `api product: ${displayName}`;
    const lifecycle = product.metadata.labels?.lifecycle || "production";
    const owner = product.metadata.annotations?.["backstage.io/owner"];
    if (!owner) {
      console.warn(`apiproduct ${namespace}/${name} has no backstage.io/owner annotation, skipping catalog sync`);
      return null;
    }
    const tags = product.spec.tags || [];
    const definition = product.status?.openapi?.raw ? `${product.status.openapi.raw}` : `# no openapi spec configured
      openapi: 3.0.0
      info:
        title: ${displayName}
        version: ${product.spec.version || "1.0.0"}
        description: ${description}
    `;
    const authSchemes = product.status?.discoveredAuthScheme?.authentication || {};
    const schemeObjects = Object.values(authSchemes);
    const hasApiKey = schemeObjects.some(
      (scheme) => scheme.hasOwnProperty("apiKey")
    );
    const entity = {
      apiVersion: "backstage.io/v1alpha1",
      kind: "API",
      metadata: {
        name: `${name}`,
        namespace: "default",
        title: displayName,
        description,
        annotations: {
          "backstage.io/managed-by-location": `kuadrant:${namespace}/${name}`,
          "backstage.io/managed-by-origin-location": `kuadrant:${namespace}/${name}`,
          "backstage.io/orphan-strategy": "keep",
          "kuadrant.io/namespace": namespace,
          "kuadrant.io/apiproduct": name,
          "kuadrant.io/auth-apikey": hasApiKey.toString(),
          // add httproute annotation if we can infer it (usually same as apiproduct name without -api suffix)
          "kuadrant.io/httproute": name.endsWith("-api") ? name.slice(0, -4) : name,
          ...product.spec.documentation?.openAPISpecURL && {
            "kuadrant.io/openapi-spec-url": product.spec.documentation.openAPISpecURL
          },
          ...product.spec.documentation?.docsURL && {
            "kuadrant.io/docs-url": product.spec.documentation.docsURL
          },
          ...product.spec.documentation?.gitRepository && {
            "backstage.io/source-location": `url:${product.spec.documentation.gitRepository}`
          },
          ...product.spec.documentation?.techdocsRef && {
            "backstage.io/techdocs-ref": product.spec.documentation.techdocsRef
          },
          ...product.spec.contact?.email && {
            "kuadrant.io/contact-email": product.spec.contact.email
          },
          ...product.spec.contact?.slack && {
            "kuadrant.io/contact-slack": product.spec.contact.slack
          }
        },
        tags: [...tags, "kuadrant", "apiproduct"],
        labels: {
          "kuadrant.io/synced": "true",
          ...product.metadata.labels || {}
        }
      },
      spec: {
        type: "openapi",
        lifecycle,
        owner,
        definition
      }
    };
    return entity;
  }
}

exports.APIProductEntityProvider = APIProductEntityProvider;
//# sourceMappingURL=APIProductEntityProvider.cjs.js.map
