/**
 * WebSocket utility functions
 */

/**
 * Type for WebSocket RawData that can be different types in different environments
 * This matches the ws library's type definition
 */
export type RawData = Buffer | ArrayBuffer | Buffer[] | any;

/**
 * Get the length of a WebSocket message regardless of its type
 * (handles all possible WebSocket message data types)
 * 
 * @param data - The data message from WebSocket (could be any RawData type)
 * @returns The length of the data in bytes
 */
export function getMessageSize(data: RawData): number {
  if (typeof data === 'string') {
    // For string data, get the byte length
    return Buffer.from(data, 'utf8').length;
  } else if (data instanceof Buffer) {
    // For Node.js Buffer
    return data.length;
  } else if (data instanceof ArrayBuffer) {
    // For ArrayBuffer
    return data.byteLength;
  } else if (Array.isArray(data)) {
    // For array of buffers, sum their lengths
    return data.reduce((sum, chunk) => {
      if (chunk instanceof Buffer) {
        return sum + chunk.length;
      } else if (chunk instanceof ArrayBuffer) {
        return sum + chunk.byteLength;
      }
      return sum;
    }, 0);
  } else {
    // For other types, try to determine the size or return 0
    try {
      return Buffer.from(data).length;
    } catch (e) {
      console.warn('Could not determine message size', e);
      return 0;
    }
  }
}

/**
 * Convert any raw WebSocket data to Buffer for consistent handling
 * 
 * @param data - The data message from WebSocket (could be any RawData type)
 * @returns A Buffer containing the data
 */
export function toBuffer(data: RawData): Buffer {
  if (typeof data === 'string') {
    return Buffer.from(data, 'utf8');
  } else if (data instanceof Buffer) {
    return data;
  } else if (data instanceof ArrayBuffer) {
    return Buffer.from(data);
  } else if (Array.isArray(data)) {
    // For array of buffers, concatenate them
    return Buffer.concat(data.map(chunk => {
      if (chunk instanceof Buffer) {
        return chunk;
      } else if (chunk instanceof ArrayBuffer) {
        return Buffer.from(chunk);
      }
      return Buffer.from(chunk);
    }));
  } else {
    // For other types, try to convert to Buffer or return empty Buffer
    try {
      return Buffer.from(data);
    } catch (e) {
      console.warn('Could not convert message to Buffer', e);
      return Buffer.alloc(0);
    }
  }
}