"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var MockFetch_exports = {};
__export(MockFetch_exports, {
  MockFetch: () => MockFetch
});
module.exports = __toCommonJS(MockFetch_exports);
var import_Function = require("./Function.js");
/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
class MockFetch extends import_Function.Callable {
  responses = [];
  originalFetch;
  callLog = [];
  installed = false;
  constructor() {
    super((url, options) => this.mockFetch(url, options));
    this.originalFetch = globalThis.fetch;
  }
  /**
   * Add a mock response for a specific URL pattern.
   *
   * @param urlPattern - String or RegExp to match against request URLs
   * @param responseData - Data to return (will be serialized to JSON or returned as binary)
   * @param options - Optional configuration for status code and binary responses
   */
  addResponse(urlPattern, responseData, options) {
    this.responses.push({
      url: urlPattern,
      responseData,
      options
    });
  }
  /**
   * Install this mock as the global fetch implementation.
   * Must be called before the code under test executes fetch calls.
   */
  install() {
    if (this.installed) {
      throw new Error("MockFetch is already installed");
    }
    globalThis.fetch = this.mockFetch.bind(this);
    this.installed = true;
  }
  /**
   * Restore the original fetch implementation and clear all mocks.
   */
  uninstall() {
    if (!this.installed) {
      return;
    }
    globalThis.fetch = this.originalFetch;
    this.installed = false;
    this.responses = [];
    this.callLog = [];
  }
  /**
   * Get a log of all fetch calls that were made.
   * Useful for verifying that expected requests were made.
   *
   * @returns Array of call log entries with URL and options
   */
  getCallLog() {
    return this.callLog;
  }
  /**
   * Clear all registered mock responses.
   */
  clearResponses() {
    this.responses = [];
  }
  /**
   * Clear the call log.
   */
  clearCallLog() {
    this.callLog = [];
  }
  /**
   * Clear both responses and call log.
   */
  clear() {
    this.clearResponses();
    this.clearCallLog();
  }
  /**
   * Internal mock fetch implementation.
   */
  async mockFetch(url, options) {
    const urlString = url.toString();
    this.callLog.push({ url: urlString, options });
    for (let i = this.responses.length - 1; i >= 0; i--) {
      const mock = this.responses[i];
      const matches = typeof mock.url === "string" ? urlString.includes(mock.url) : mock.url.test(urlString);
      if (matches) {
        const status = mock.options?.status ?? 200;
        const ok = status >= 200 && status < 300;
        const response = {
          ok,
          status,
          statusText: ok ? "OK" : "Error",
          ...mock.options?.binary ? {
            // Create a NEW ReadableStream for each fetch
            body: new ReadableStream({
              start(controller) {
                const data = mock.responseData instanceof Uint8Array ? mock.responseData : new Uint8Array(mock.responseData);
                controller.enqueue(data);
                controller.close();
              }
            }),
            arrayBuffer: async () => {
              if (mock.responseData instanceof Uint8Array) {
                return mock.responseData.buffer;
              }
              return mock.responseData;
            }
          } : {
            json: async () => mock.responseData,
            text: async () => JSON.stringify(mock.responseData)
          }
        };
        return response;
      }
    }
    throw new Error(`No mock found for URL: ${urlString}`);
  }
}
//# sourceMappingURL=MockFetch.js.map
