/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
import { Logger, MatterError, Seconds } from "#general";
const logger = new Logger("DclClient");
const DCL_PRODUCTION_URL = "https://on.dcl.csa-iot.org";
const DCL_TEST_URL = "https://on.test-net.dcl.csa-iot.org";
const DEFAULT_DCL_TIMEOUT = Seconds(5);
class MatterDclError extends MatterError {
}
class MatterDclResponseError extends MatterDclError {
  response;
  constructor(path, error, options) {
    super(`Error fetching ${path} from DCL: ${error.code} - ${error.message}`, options);
    this.response = error;
  }
}
class DclClient {
  constructor(production = true) {
    this.production = production;
    this.#baseUrl = this.production ? DCL_PRODUCTION_URL : DCL_TEST_URL;
  }
  #baseUrl;
  async #fetchPaginatedJson(path, paginatedField, options) {
    const allItems = [];
    let nextKey;
    do {
      const currentPath = nextKey !== void 0 ? `${path}${path.includes("?") ? "&" : "?"}pagination.key=${encodeURIComponent(nextKey)}` : path;
      const response = await this.#fetchJson(currentPath, options);
      const items = response[paginatedField];
      if (items && Array.isArray(items)) {
        allItems.push(...items);
      }
      nextKey = response?.pagination?.next_key;
    } while (nextKey);
    return allItems;
  }
  async #fetchJson(path, options) {
    const url = new URL(path, this.#baseUrl).toString();
    logger.debug(`Fetching for DCL:`, url);
    try {
      const timeoutMs = options?.timeout ?? DEFAULT_DCL_TIMEOUT;
      const response = await fetch(url, {
        method: "GET",
        headers: {
          "Content-Type": "application/json"
        },
        signal: AbortSignal.timeout(timeoutMs)
      });
      if (!response.ok) {
        throw new MatterDclResponseError(path, await response.json());
      }
      return await response.json();
    } catch (error) {
      MatterDclResponseError.reject(error);
      throw new MatterDclResponseError(
        path,
        {
          code: 500,
          message: error.message ?? error,
          details: []
        },
        { cause: error }
      );
    }
  }
  async fetchRootCertificateList(options) {
    const certList = await this.#fetchJson("/dcl/pki/root-certificates", options);
    if (certList?.approvedRootCertificates?.schemaVersion !== 0) {
      throw new MatterDclError(
        `Unsupported DCL Root Certificate schema version: ${certList.approvedRootCertificates.schemaVersion}`
      );
    }
    return certList.approvedRootCertificates.certs;
  }
  async fetchRootCertificateBySubject(subject, options) {
    const path = `/dcl/pki/certificates/${encodeURIComponent(subject.subject)}/${encodeURIComponent(subject.subjectKeyId)}`;
    const response = await this.#fetchJson(path, options);
    if (!response || !response.approvedCertificates || response.approvedCertificates.subject !== subject.subject || response.approvedCertificates.subjectKeyId !== subject.subjectKeyId || response.approvedCertificates.schemaVersion !== 0) {
      throw new MatterDclError(
        `Root certificate not found for subject: ${subject.subject}, subjectKeyId: ${subject.subjectKeyId}`
      );
    }
    return response.approvedCertificates.certs;
  }
  async fetchModelByVidPid(vid, pid, options) {
    const path = `/dcl/model/models/${encodeURIComponent(vid)}/${encodeURIComponent(pid)}`;
    const response = await this.#fetchJson(path, options);
    if (!response || !response.model || response.model.vid !== vid || response.model.pid !== pid || response.model.schemaVersion !== 0) {
      throw new MatterDclError(`Model not found for VID: ${vid}, PID: ${pid}`);
    }
    return response.model;
  }
  async fetchModelVersionsByVidPid(vid, pid, options) {
    const path = `/dcl/model/versions/${encodeURIComponent(vid)}/${encodeURIComponent(pid)}`;
    const response = await this.#fetchJson(path, options);
    if (!response || !response.modelVersions || response.modelVersions.vid !== vid || response.modelVersions.pid !== pid || response.modelVersions.schemaVersion !== 0) {
      throw new MatterDclError(`Model versions not found for VID: ${vid}, PID: ${pid}`);
    }
    return response.modelVersions.softwareVersions;
  }
  async fetchModelVersionByVidPidSoftwareVersion(vid, pid, softwareVersion, options) {
    const path = `/dcl/model/versions/${encodeURIComponent(vid)}/${encodeURIComponent(pid)}/${encodeURIComponent(softwareVersion)}`;
    const response = await this.#fetchJson(path, options);
    if (!response || !response.modelVersion || response.modelVersion.vid !== vid || response.modelVersion.pid !== pid || response.modelVersion.softwareVersion !== softwareVersion || response.modelVersion.schemaVersion !== 0) {
      throw new MatterDclError(
        `Model version not found for VID: ${vid}, PID: ${pid}, Software Version: ${softwareVersion}`
      );
    }
    return response.modelVersion;
  }
  /**
   * Fetch all vendor information from DCL
   */
  async fetchAllVendors(options) {
    return this.#fetchPaginatedJson("/dcl/vendorinfo/vendors", "vendorInfo", options);
  }
}
export {
  DclClient,
  MatterDclError,
  MatterDclResponseError
};
//# sourceMappingURL=DclClient.js.map
