import type { NetworkMessage } from '@network-tool/shared-types';

/**
 * 消息帧格式:
 * ┌──────────────┬──────────────────┐
 * │  Header (4B) │  Payload (JSON)  │
 * │  msg length  │  UTF-8 bytes     │
 * └──────────────┴──────────────────┘
 */

export const PROTOCOL_VERSION = 1;
export const FRAME_HEADER_SIZE = 4; // 4 bytes for length prefix

/**
 * 编码消息为网络传输格式
 */
export function encodeMessage(msg: NetworkMessage): Buffer {
  const json = JSON.stringify(msg);
  const payload = Buffer.from(json, 'utf-8');
  const header = Buffer.alloc(FRAME_HEADER_SIZE);
  header.writeUInt32BE(payload.length, 0);
  return Buffer.concat([header, payload]);
}

/**
 * 解码网络消息
 */
export function decodeMessage(data: Buffer): NetworkMessage {
  const json = data.toString('utf-8');
  return JSON.parse(json) as NetworkMessage;
}

/**
 * 从流式数据中提取帧（处理粘包/拆包）
 */
export class FrameParser {
  private buffer: Buffer = Buffer.alloc(0);

  push(chunk: Buffer): NetworkMessage[] {
    this.buffer = Buffer.concat([this.buffer, chunk]);
    const messages: NetworkMessage[] = [];

    while (this.buffer.length >= FRAME_HEADER_SIZE) {
      const payloadLength = this.buffer.readUInt32BE(0);
      const totalLength = FRAME_HEADER_SIZE + payloadLength;

      if (this.buffer.length < totalLength) {
        break; // 数据不完整，等待更多数据
      }

      const payload = this.buffer.subarray(FRAME_HEADER_SIZE, totalLength);
      try {
        messages.push(decodeMessage(payload));
      } catch {
        // 跳过损坏的消息
      }
      this.buffer = this.buffer.subarray(totalLength);
    }

    return messages;
  }

  reset(): void {
    this.buffer = Buffer.alloc(0);
  }
}
