/**
 * 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 { parseDateToInt } from "./DataTypes";

/**
 * Fast serialization utilities for IoTDB data types
 * Optimized for performance with:
 * - Single exact-size buffer allocation per tablet (no Buffer.concat re-copy)
 * - BigInt-free int64 writes (hi/lo 32-bit pair)
 * - Single-entry string encode cache (TAG columns repeat the same value)
 * - Minimal object allocation
 */

/**
 * Write a 64-bit big-endian signed integer without allocating a BigInt.
 *
 * For any safe integer v (positive or negative):
 *   hi = Math.floor(v / 2^32)  — arithmetic shift, sign-correct
 *   lo = v >>> 0               — ToUint32 performs the mod-2^32 reduction
 * so that hi * 2^32 + lo === v, which is exactly the two's complement
 * representation split into two 32-bit halves.
 *
 * Falls back to writeBigInt64BE for BigInt inputs and non-safe-integer
 * numbers (preserves legacy error behavior for invalid values like 1.5).
 */
export function writeInt64BE(buffer: Buffer, v: number | bigint, offset: number): void {
  if (typeof v === "number" && Number.isSafeInteger(v)) {
    buffer.writeInt32BE(Math.floor(v / 0x100000000), offset);
    buffer.writeUInt32BE(v >>> 0, offset + 4);
  } else {
    buffer.writeBigInt64BE(typeof v === "bigint" ? v : BigInt(v as any), offset);
  }
}

/**
 * Byte length of a BLOB cell value without materializing a Buffer.
 * Accepts Buffer, Uint8Array, UTF-8 string, or array-like of bytes
 * (the same inputs the legacy serializer accepted via Buffer.from).
 */
function blobByteLength(v: any): number {
  if (Buffer.isBuffer(v) || v instanceof Uint8Array) {
    return v.length;
  }
  if (typeof v === "string") {
    return Buffer.byteLength(v, "utf8");
  }
  if (isArrayBufferLike(v)) {
    return v.byteLength; // ArrayBuffer / SharedArrayBuffer have no .length
  }
  return v.length; // array-like of bytes
}

/** ArrayBuffer / SharedArrayBuffer (raw memory, no .length property). */
function isArrayBufferLike(v: any): v is ArrayBufferLike {
  return (
    v instanceof ArrayBuffer ||
    (typeof SharedArrayBuffer !== "undefined" && v instanceof SharedArrayBuffer)
  );
}

/**
 * Serialize BOOLEAN column (1 byte per value)
 */
export function serializeBooleanColumn(values: any[]): Buffer {
  const buffer = Buffer.allocUnsafe(values.length);
  for (let i = 0; i < values.length; i++) {
    const v = values[i];
    buffer[i] = (v === null || v === undefined) ? 0 : (v ? 1 : 0);
  }
  return buffer;
}

/**
 * Serialize INT32 column (4 bytes per value, big-endian)
 */
export function serializeInt32Column(values: any[]): Buffer {
  const buffer = Buffer.allocUnsafe(values.length * 4);
  for (let i = 0; i < values.length; i++) {
    const v = values[i];
    buffer.writeInt32BE(v === null || v === undefined ? 0 : v, i * 4);
  }
  return buffer;
}

/**
 * Serialize INT64 column (8 bytes per value, big-endian)
 * Optimized: BigInt-free hi/lo writes for number inputs
 */
export function serializeInt64Column(values: any[]): Buffer {
  const buffer = Buffer.allocUnsafe(values.length * 8);
  for (let i = 0; i < values.length; i++) {
    const v = values[i];
    if (v === null || v === undefined) {
      buffer.writeInt32BE(0, i * 8);
      buffer.writeUInt32BE(0, i * 8 + 4);
    } else {
      writeInt64BE(buffer, v, i * 8);
    }
  }
  return buffer;
}

/**
 * Serialize FLOAT column (4 bytes per value, big-endian)
 */
export function serializeFloatColumn(values: any[]): Buffer {
  const buffer = Buffer.allocUnsafe(values.length * 4);
  for (let i = 0; i < values.length; i++) {
    const v = values[i];
    buffer.writeFloatBE(v === null || v === undefined ? 0.0 : v, i * 4);
  }
  return buffer;
}

/**
 * Serialize DOUBLE column (8 bytes per value, big-endian)
 */
export function serializeDoubleColumn(values: any[]): Buffer {
  const buffer = Buffer.allocUnsafe(values.length * 8);
  for (let i = 0; i < values.length; i++) {
    const v = values[i];
    buffer.writeDoubleBE(v === null || v === undefined ? 0.0 : v, i * 8);
  }
  return buffer;
}

/**
 * Serialize TEXT/STRING column (4 bytes length + UTF-8 bytes per value)
 * Optimized: single-entry encode cache — TAG columns repeat the same string
 * for every row of a tablet, so the encoded Buffer is reused on consecutive
 * identical values instead of re-encoding.
 */
export function serializeTextColumn(values: any[]): Buffer {
  // Phase 1: Calculate total size (byteLength only — no Buffer allocation)
  let totalSize = 0;
  let lastSizeStr: string | null = null;
  let lastSizeLen = 0;

  for (const v of values) {
    if (v === null || v === undefined) {
      totalSize += 4;
      continue;
    }
    const str = typeof v === "string" ? v : String(v);
    if (str !== lastSizeStr) {
      lastSizeLen = Buffer.byteLength(str, "utf8");
      lastSizeStr = str;
    }
    totalSize += 4 + lastSizeLen;
  }

  // Phase 2: Single allocation, encode with single-entry cache
  const result = Buffer.allocUnsafe(totalSize);
  let offset = 0;
  let lastStr: string | null = null;
  let lastBuf: Buffer | null = null;

  for (const v of values) {
    if (v === null || v === undefined) {
      result.writeInt32BE(0, offset);
      offset += 4;
      continue;
    }
    const str = typeof v === "string" ? v : String(v);
    if (str !== lastStr || lastBuf === null) {
      lastBuf = Buffer.from(str, "utf8");
      lastStr = str;
    }
    result.writeInt32BE(lastBuf.length, offset);
    offset += 4;
    lastBuf.copy(result, offset);
    offset += lastBuf.length;
  }

  return result;
}

/**
 * Serialize TIMESTAMP column (8 bytes per value, big-endian)
 * Handles both Date objects and numeric timestamps
 * Optimized: BigInt-free hi/lo writes
 */
export function serializeTimestampColumn(values: any[]): Buffer {
  const buffer = Buffer.allocUnsafe(values.length * 8);
  for (let i = 0; i < values.length; i++) {
    const v = values[i];
    if (v === null || v === undefined) {
      buffer.writeInt32BE(0, i * 8);
      buffer.writeUInt32BE(0, i * 8 + 4);
    } else {
      writeInt64BE(buffer, v instanceof Date ? v.getTime() : v, i * 8);
    }
  }
  return buffer;
}

/**
 * Serialize DATE column (4 bytes per value, INT32 yyyyMMdd encoding)
 */
export function serializeDateColumn(values: any[]): Buffer {
  const buffer = Buffer.allocUnsafe(values.length * 4);
  for (let i = 0; i < values.length; i++) {
    const v = values[i];
    const encoded = v === null || v === undefined ? 0 : parseDateToInt(v);
    buffer.writeInt32BE(encoded, i * 4);
  }
  return buffer;
}

/**
 * Serialize BLOB column (4 bytes length + binary data per value)
 * Two-pass approach to pre-calculate total size
 */
export function serializeBlobColumn(values: any[]): Buffer {
  // Phase 1: Calculate total size and prepare blob buffers
  const blobBuffers: Buffer[] = [];
  let totalSize = 0;

  for (const v of values) {
    const blob = v === null || v === undefined
      ? Buffer.alloc(0)
      : Buffer.isBuffer(v)
        ? v
        : Buffer.from(v);
    blobBuffers.push(blob);
    totalSize += 4 + blob.length;
  }

  // Phase 2: Single allocation and copy
  const result = Buffer.allocUnsafe(totalSize);
  let offset = 0;

  for (const blob of blobBuffers) {
    result.writeInt32BE(blob.length, offset);
    offset += 4;
    blob.copy(result, offset);
    offset += blob.length;
  }

  return result;
}

/**
 * Serialize timestamps array to buffer (used by insertTablet)
 * Optimized: BigInt-free hi/lo writes (timestamps are safe integers)
 */
export function serializeTimestamps(timestamps: number[]): Buffer {
  const buffer = Buffer.allocUnsafe(timestamps.length * 8);
  for (let i = 0; i < timestamps.length; i++) {
    const t = timestamps[i];
    if (typeof t !== "number" || !Number.isFinite(t)) {
      throw new Error(`Invalid timestamp at index ${i}: ${t}`);
    }
    const v = Math.floor(t);
    buffer.writeInt32BE(Math.floor(v / 0x100000000), i * 8);
    buffer.writeUInt32BE(v >>> 0, i * 8 + 4);
  }
  return buffer;
}

/**
 * Fast column serializer dispatch
 * Maps data type to appropriate serialization function
 */
export function serializeColumnFast(values: any[], dataType: number): Buffer {
  switch (dataType) {
    case 0: // BOOLEAN
      return serializeBooleanColumn(values);
    case 1: // INT32
      return serializeInt32Column(values);
    case 2: // INT64
      return serializeInt64Column(values);
    case 3: // FLOAT
      return serializeFloatColumn(values);
    case 4: // DOUBLE
      return serializeDoubleColumn(values);
    case 5: // TEXT
    case 11: // STRING
      return serializeTextColumn(values);
    case 8: // TIMESTAMP
      return serializeTimestampColumn(values);
    case 9: // DATE
      return serializeDateColumn(values);
    case 10: // BLOB
    case 12: // OBJECT (same length-prefixed binary encoding)
      return serializeBlobColumn(values);
    default:
      throw new Error(`Unsupported data type: ${dataType}`);
  }
}

/**
 * Serialize a whole tablet's values (all columns + null bitmaps) into ONE buffer.
 *
 * Wire format (identical to the legacy per-column path):
 *   [col0 data][col1 data]...[colN data]
 *   then per column: [hasNull flag byte][bitmap bytes, only when flag=1]
 *   Bitmap: ceil(rowCount/8) bytes, LSB-first, bit=1 means NULL.
 *
 * Optimizations over the legacy path:
 * - No rows→columns transpose (reads values[row][col] directly)
 * - No per-column intermediate buffers or boolean[] bitmaps
 * - No trailing Buffer.concat (exact data size pre-computed; bitmap section
 *   allocated worst-case and trimmed with a zero-copy subarray)
 * - Null bitmaps are packed inline during the value pass; the flag byte
 *   stays 0 and no bitmap bytes are emitted when a column has no nulls
 *
 * @param values Row-major tablet values: values[rowIndex][colIndex]
 * @param dataTypes TSDataType code per column
 * @param rowCount Number of rows
 */
export function serializeTabletValuesFast(
  values: any[][],
  dataTypes: number[],
  rowCount: number,
): Buffer {
  const numCols = dataTypes.length;
  const bitmapBytes = Math.ceil(rowCount / 8);

  // ---- Pass 1: exact data-section size (fixed widths from schema; one
  // byteLength scan for variable-width columns, memoizing repeated strings) ----
  let dataSize = 0;
  for (let c = 0; c < numCols; c++) {
    switch (dataTypes[c]) {
      case 0: // BOOLEAN
        dataSize += rowCount;
        break;
      case 1: // INT32
      case 3: // FLOAT
      case 9: // DATE
        dataSize += rowCount * 4;
        break;
      case 2: // INT64
      case 4: // DOUBLE
      case 8: // TIMESTAMP
        dataSize += rowCount * 8;
        break;
      case 5: // TEXT
      case 11: { // STRING
        let lastStr: string | null = null;
        let lastLen = 0;
        for (let r = 0; r < rowCount; r++) {
          const v = values[r][c];
          if (v === null || v === undefined) {
            dataSize += 4;
            continue;
          }
          const str = typeof v === "string" ? v : String(v);
          if (str !== lastStr) {
            lastLen = Buffer.byteLength(str, "utf8");
            lastStr = str;
          }
          dataSize += 4 + lastLen;
        }
        break;
      }
      case 10: // BLOB
      case 12: { // OBJECT (same length-prefixed binary encoding)
        for (let r = 0; r < rowCount; r++) {
          const v = values[r][c];
          dataSize += 4 + (v === null || v === undefined ? 0 : blobByteLength(v));
        }
        break;
      }
      default:
        throw new Error(`Unsupported data type: ${dataTypes[c]}`);
    }
  }

  // Single allocation: data section + worst-case bitmap section
  // (flag byte per column + bitmap per column); trimmed at the end.
  const buffer = Buffer.allocUnsafe(dataSize + numCols * (1 + bitmapBytes));

  // ---- Pass 2: write values and pack null bitmaps inline ----
  let off = 0; // data-section write offset
  let bmOff = dataSize; // bitmap-section write offset (compact)

  for (let c = 0; c < numCols; c++) {
    const flagPos = bmOff;
    buffer[flagPos] = 0; // hasNull flag; flipped on first null
    let hasNull = false;

    // Marks row r as NULL: lazily initializes this column's bitmap region.
    const markNull = (r: number): void => {
      if (!hasNull) {
        hasNull = true;
        buffer[flagPos] = 1;
        buffer.fill(0, flagPos + 1, flagPos + 1 + bitmapBytes);
      }
      buffer[flagPos + 1 + (r >>> 3)] |= 1 << (r & 7);
    };

    switch (dataTypes[c]) {
      case 0: // BOOLEAN
        for (let r = 0; r < rowCount; r++) {
          const v = values[r][c];
          if (v === null || v === undefined) {
            markNull(r);
            buffer[off] = 0;
          } else {
            buffer[off] = v ? 1 : 0;
          }
          off += 1;
        }
        break;
      case 1: // INT32
        for (let r = 0; r < rowCount; r++) {
          const v = values[r][c];
          if (v === null || v === undefined) {
            markNull(r);
            buffer.writeInt32BE(0, off);
          } else {
            buffer.writeInt32BE(v, off);
          }
          off += 4;
        }
        break;
      case 2: // INT64
        for (let r = 0; r < rowCount; r++) {
          const v = values[r][c];
          if (v === null || v === undefined) {
            markNull(r);
            buffer.writeInt32BE(0, off);
            buffer.writeUInt32BE(0, off + 4);
          } else {
            writeInt64BE(buffer, v, off);
          }
          off += 8;
        }
        break;
      case 3: // FLOAT
        for (let r = 0; r < rowCount; r++) {
          const v = values[r][c];
          if (v === null || v === undefined) {
            markNull(r);
            buffer.writeFloatBE(0.0, off);
          } else {
            buffer.writeFloatBE(v, off);
          }
          off += 4;
        }
        break;
      case 4: // DOUBLE
        for (let r = 0; r < rowCount; r++) {
          const v = values[r][c];
          if (v === null || v === undefined) {
            markNull(r);
            buffer.writeDoubleBE(0.0, off);
          } else {
            buffer.writeDoubleBE(v, off);
          }
          off += 8;
        }
        break;
      case 5: // TEXT
      case 11: { // STRING
        // Single-entry encode cache: TAG columns repeat one string per tablet
        let lastStr: string | null = null;
        let lastBuf: Buffer | null = null;
        for (let r = 0; r < rowCount; r++) {
          const v = values[r][c];
          if (v === null || v === undefined) {
            markNull(r);
            buffer.writeInt32BE(0, off);
            off += 4;
            continue;
          }
          const str = typeof v === "string" ? v : String(v);
          if (str !== lastStr || lastBuf === null) {
            lastBuf = Buffer.from(str, "utf8");
            lastStr = str;
          }
          buffer.writeInt32BE(lastBuf.length, off);
          off += 4;
          lastBuf.copy(buffer, off);
          off += lastBuf.length;
        }
        break;
      }
      case 8: // TIMESTAMP
        for (let r = 0; r < rowCount; r++) {
          const v = values[r][c];
          if (v === null || v === undefined) {
            markNull(r);
            buffer.writeInt32BE(0, off);
            buffer.writeUInt32BE(0, off + 4);
          } else {
            writeInt64BE(buffer, v instanceof Date ? v.getTime() : v, off);
          }
          off += 8;
        }
        break;
      case 9: // DATE (INT32 yyyyMMdd encoding)
        for (let r = 0; r < rowCount; r++) {
          const v = values[r][c];
          if (v === null || v === undefined) {
            markNull(r);
            buffer.writeInt32BE(0, off);
          } else {
            buffer.writeInt32BE(parseDateToInt(v), off);
          }
          off += 4;
        }
        break;
      case 10: // BLOB
      case 12: { // OBJECT (same length-prefixed binary encoding)
        for (let r = 0; r < rowCount; r++) {
          const v = values[r][c];
          if (v === null || v === undefined) {
            markNull(r);
            buffer.writeInt32BE(0, off);
            off += 4;
            continue;
          }
          // Write directly into the target buffer — no intermediate
          // Buffer.from() materialization (sizing used blobByteLength).
          const len = blobByteLength(v);
          buffer.writeInt32BE(len, off);
          off += 4;
          if (Buffer.isBuffer(v)) {
            v.copy(buffer, off);
          } else if (v instanceof Uint8Array) {
            buffer.set(v, off);
          } else if (typeof v === "string") {
            buffer.write(v, off, "utf8");
          } else if (isArrayBufferLike(v)) {
            // Raw memory: wrap in a zero-copy Uint8Array view to bulk-copy.
            buffer.set(new Uint8Array(v), off);
          } else {
            // Array-like of bytes (legacy accepted input)
            for (let i = 0; i < len; i++) {
              buffer[off + i] = v[i];
            }
          }
          off += len;
        }
        break;
      }
      default:
        throw new Error(`Unsupported data type: ${dataTypes[c]}`);
    }

    bmOff = flagPos + 1 + (hasNull ? bitmapBytes : 0);
  }

  // Zero-copy trim: unused worst-case bitmap space is dropped
  return buffer.subarray(0, bmOff);
}
