"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 accessory_server_exports = {};
__export(accessory_server_exports, {
  AccessoryMethodError: () => AccessoryMethodError,
  AccessoryServer: () => AccessoryServer
});
module.exports = __toCommonJS(accessory_server_exports);
var import_node_http = require("node:http");
var import_xml2js = require("xml2js");
/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
class AccessoryMethodError extends Error {
  constructor(message, status = 400) {
    super(message);
    this.status = status;
  }
  status;
}
class AccessoryServer {
  #server;
  #isClosed = false;
  #subject;
  constructor(subject, onReady) {
    this.#subject = subject;
    this.#server = (0, import_node_http.createServer)(this.#handleRequest.bind(this));
    this.#server.listen(0, "127.0.0.1", onReady);
  }
  static create(subject) {
    return new Promise((resolve) => {
      const server = new AccessoryServer(subject, () => resolve(server));
    });
  }
  get port() {
    const port = this.#server.address()?.port;
    if (typeof port !== "number") {
      throw new Error("Accessory server has no assigned port");
    }
    return port;
  }
  async close() {
    if (!this.#isClosed) {
      this.#isClosed = true;
      await new Promise(
        (resolve) => this.#server.close((error) => {
          if (error) {
            console.warn("Error closing accessory server", error);
          }
          resolve();
        })
      );
    }
  }
  #handleRequest(request, response) {
    request.on("error", (error) => {
      console.warn("Accessory server request error", error);
    });
    response.on("error", (error) => {
      console.warn("Accessory server response error", error);
    });
    const parser = new import_xml2js.Parser();
    request.on("data", (chunk) => {
      parser.parseString(chunk, (error, result) => {
        if (error) {
          response.writeHead(400);
          response.end();
          return;
        }
        if (result !== void 0) {
          this.#invoke(result).then(
            () => {
              response.writeHead(200);
              response.end(
                `<?xml version="1.0"?>
<methodResponse><params><param><value><boolean>1</boolean></value></param></params></methodResponse>`
              );
            },
            (error2) => {
              const status = error2 instanceof AccessoryMethodError ? error2.status : 500;
              console.warn(`Accessory invocation error (HTTP ${status}):`, error2);
              response.writeHead(status);
              response.end();
            }
          );
        }
      });
    });
  }
  async #invoke(request) {
    const methodName = request?.methodCall?.methodName?.[0];
    if (typeof methodName !== "string") {
      throw new AccessoryMethodError("Missing or invalid accessory method name");
    }
    switch (methodName) {
      case "reboot":
      case "factoryReset":
      case "start":
      case "stop":
        await this.#subject.backchannel({ name: methodName });
        return;
      case "waitForMessage":
      case "createOtaImage":
      case "compareFiles":
      case "createFile":
      case "deleteFile":
        throw new AccessoryMethodError(`Unimplemented accessory method ${methodName}`, 404);
    }
    throw new AccessoryMethodError(`Unsupported accessory method ${methodName}`, 404);
  }
}
//# sourceMappingURL=accessory-server.js.map
