/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import { logger } from "./Logger";

/**
 * Buffer pool for reusing buffers to reduce GC pressure
 * Inspired by pg nodejs client's buffer management strategy
 * 
 * Key design principles:
 * 1. Size classes to minimize waste (powers of 2)
 * 2. Maximum pool size to prevent memory bloat
 * 3. Clear statistics for monitoring
 */
export class BufferPool {
  // Size classes: 1KB, 4KB, 16KB, 64KB, 256KB, 1MB, 4MB
  private static readonly SIZE_CLASSES = [
    1024,       // 1KB
    4096,       // 4KB
    16384,      // 16KB
    65536,      // 64KB
    262144,     // 256KB
    1048576,    // 1MB
    4194304,    // 4MB
  ];
  
  // Maximum buffers per size class
  private static readonly MAX_BUFFERS_PER_CLASS = 10;
  
  // Pools organized by size class
  private pools: Map<number, Buffer[]>;
  
  // Statistics
  private stats = {
    hits: 0,
    misses: 0,
    allocations: 0,
    returns: 0,
  };

  constructor() {
    this.pools = new Map();
    for (const size of BufferPool.SIZE_CLASSES) {
      this.pools.set(size, []);
    }
  }

  /**
   * Get a buffer of at least the requested size
   * Returns a pooled buffer if available, otherwise allocates new
   * @throws Error if buffer allocation fails (e.g., out of memory)
   */
  acquire(minSize: number): Buffer {
    // Find appropriate size class
    const sizeClass = this.getSizeClass(minSize);

    try {
      if (sizeClass === null) {
        // Size too large for pooling, allocate directly
        this.stats.misses++;
        this.stats.allocations++;
        return Buffer.allocUnsafe(minSize);
      }

      const pool = this.pools.get(sizeClass);
      if (!pool) {
        this.stats.misses++;
        this.stats.allocations++;
        return Buffer.allocUnsafe(sizeClass);
      }

      const buffer = pool.pop();
      if (buffer) {
        this.stats.hits++;
        // Return the full buffer from the pool (will be sized to sizeClass)
        // The caller is responsible for using only minSize bytes
        return buffer.subarray(0, minSize);
      } else {
        this.stats.misses++;
        this.stats.allocations++;
        return Buffer.allocUnsafe(sizeClass);
      }
    } catch (error) {
      const message = error instanceof Error ? error.message : String(error);
      throw new Error(`Buffer allocation failed for size ${minSize}: ${message}`);
    }
  }

  /**
   * Return a buffer to the pool for reuse
   * Only pools buffers that fit in size classes
   */
  release(buffer: Buffer): void {
    const sizeClass = this.getSizeClass(buffer.length);
    
    if (sizeClass === null) {
      // Buffer too large for pooling, let GC handle it
      return;
    }

    const pool = this.pools.get(sizeClass);
    if (!pool) {
      return;
    }

    // Only pool if we haven't hit the limit
    if (pool.length < BufferPool.MAX_BUFFERS_PER_CLASS) {
      // Only pool if it matches the size class exactly
      if (buffer.length === sizeClass) {
        pool.push(buffer);
        this.stats.returns++;
      }
    }
  }

  /**
   * Find the appropriate size class for a requested size
   * Returns null if size is too large for pooling
   */
  private getSizeClass(size: number): number | null {
    for (const sizeClass of BufferPool.SIZE_CLASSES) {
      if (size <= sizeClass) {
        return sizeClass;
      }
    }
    return null; // Too large for pooling
  }

  /**
   * Get pool statistics
   */
  getStats() {
    const hitRate = this.stats.hits + this.stats.misses > 0
      ? (this.stats.hits / (this.stats.hits + this.stats.misses) * 100).toFixed(2)
      : '0.00';
    
    const pooledBuffers = Array.from(this.pools.values()).reduce(
      (sum, pool) => sum + pool.length,
      0
    );

    return {
      ...this.stats,
      hitRate: `${hitRate}%`,
      pooledBuffers,
    };
  }

  /**
   * Clear all pooled buffers
   */
  clear(): void {
    for (const pool of this.pools.values()) {
      pool.length = 0;
    }
    logger.debug('BufferPool cleared');
  }

  /**
   * Log statistics (for debugging)
   */
  logStats(): void {
    const stats = this.getStats();
    logger.debug(`BufferPool stats: ${JSON.stringify(stats)}`);
  }
}

// Global singleton instance
export const globalBufferPool = new BufferPool();
