/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
import { DataReader, DataWriter, Endian } from "#general";
import { BdxStatusCode, Schema } from "#types";
import { BdxError } from "../BdxError.js";
import {
  BDX_VERSION,
  BdxRangeControlSchema,
  BdxTransferControlSchema
} from "./BdxInitMessagesSchema.js";
class BdxSendAcceptMessageSchema extends Schema {
  encodeInternal(message) {
    this.validate(message);
    const { transferControl, maxBlockSize, metaData } = message;
    const writer = new DataWriter(Endian.Little);
    writer.writeUInt8(BdxTransferControlSchema.encode(transferControl));
    writer.writeUInt16(maxBlockSize);
    if (metaData && metaData.byteLength > 0) {
      writer.writeByteArray(metaData);
    }
    return writer.toByteArray();
  }
  decodeInternal(bytes) {
    const reader = new DataReader(bytes, Endian.Little);
    const transferControl = BdxTransferControlSchema.decode(reader.readUInt8());
    const maxBlockSize = reader.readUInt16();
    const metaData = reader.remainingBytesCount > 0 ? reader.remainingBytes : void 0;
    const result = {
      transferControl,
      maxBlockSize,
      metaData
    };
    this.validate(result);
    return result;
  }
  validate({ transferControl, maxBlockSize }) {
    if (transferControl.version !== BDX_VERSION) {
      throw new BdxError(
        `Unsupported BDX version: ${transferControl.version}`,
        BdxStatusCode.VersionNotSupported
      );
    }
    if (!transferControl.senderDrive && !transferControl.receiverDrive && !transferControl.asynchronousTransfer) {
      throw new BdxError(
        "BDX transfer control need to specify at least one of sender drive, receiver drive or asynchronousTransfer",
        BdxStatusCode.BadMessageContent
      );
    }
    if (maxBlockSize < 1 || maxBlockSize > 65535) {
      throw new BdxError("Max Block Size must be between 1 and 65535bytes", BdxStatusCode.BadMessageContent);
    }
  }
}
const BdxSendAcceptMessage = new BdxSendAcceptMessageSchema();
class BdxReceiveAcceptMessageSchema extends BdxSendAcceptMessageSchema {
  encodeInternal(message) {
    this.validate(message);
    const { transferControl, maxBlockSize, metaData, length } = message;
    const rangeControl = {
      definiteLength: length !== void 0 && length !== 0,
      wideRange: typeof length === "bigint"
    };
    const writer = new DataWriter(Endian.Little);
    writer.writeUInt8(BdxTransferControlSchema.encode(transferControl));
    writer.writeUInt8(BdxRangeControlSchema.encode(rangeControl));
    writer.writeUInt16(maxBlockSize);
    if (length !== void 0 && length !== 0) {
      if (rangeControl.wideRange) {
        writer.writeUInt64(length);
      } else {
        writer.writeUInt32(length);
      }
    }
    if (metaData && metaData.byteLength > 0) {
      writer.writeByteArray(metaData);
    }
    return writer.toByteArray();
  }
  decodeInternal(bytes) {
    const reader = new DataReader(bytes, Endian.Little);
    const transferControl = BdxTransferControlSchema.decode(reader.readUInt8());
    const rangeControl = BdxRangeControlSchema.decode(reader.readUInt8());
    const maxBlockSize = reader.readUInt16();
    let length = rangeControl.definiteLength ? rangeControl.wideRange ? reader.readUInt64() : reader.readUInt32() : void 0;
    if (length === 0) {
      length = void 0;
    }
    const metaData = reader.remainingBytesCount > 0 ? reader.remainingBytes : void 0;
    const result = {
      transferControl,
      maxBlockSize,
      metaData,
      length
    };
    this.validate(result);
    return result;
  }
}
const BdxReceiveAcceptMessage = new BdxReceiveAcceptMessageSchema();
export {
  BdxReceiveAcceptMessage,
  BdxReceiveAcceptMessageSchema,
  BdxSendAcceptMessage,
  BdxSendAcceptMessageSchema
};
//# sourceMappingURL=BdxAcceptMessagesSchema.js.map
