/**
 * Byte-capped ring buffer of Buffer chunks.
 * Used by ConsoleSession to retain a bounded scrollback of PTY output
 * bytes (raw, including ANSI escape sequences). Oldest bytes are
 * dropped first when over capacity.
 */
export class ByteRingBuffer {
  private chunks: Buffer[] = [];
  private _bytes = 0;

  constructor(private readonly cap: number) {
    if (cap <= 0) throw new Error('ByteRingBuffer cap must be positive');
  }

  get bytes(): number {
    return this._bytes;
  }

  append(buf: Buffer): void {
    if (buf.length === 0) return;
    if (buf.length >= this.cap) {
      this.chunks = [buf.subarray(buf.length - this.cap)];
      this._bytes = this.cap;
      return;
    }
    this.chunks.push(buf);
    this._bytes += buf.length;
    while (this._bytes > this.cap) {
      const head = this.chunks[0]!;
      const overflow = this._bytes - this.cap;
      if (head.length <= overflow) {
        this.chunks.shift();
        this._bytes -= head.length;
      } else {
        this.chunks[0] = head.subarray(overflow);
        this._bytes -= overflow;
      }
    }
  }

  concat(): Buffer {
    return Buffer.concat(this.chunks, this._bytes);
  }

  tail(n: number): Buffer {
    if (n >= this._bytes) return this.concat();
    const full = this.concat();
    return full.subarray(full.length - n);
  }

  clear(): void {
    this.chunks = [];
    this._bytes = 0;
  }
}
