import {fromByteWidth} from './bit-width-util.js';
import {BitWidth} from './bit-width.js';
import {fromUTF8Array} from './flexbuffers-util.js';
import {
  indirect,
  keyForIndex,
  keyIndex,
  readFloat,
  readInt,
  readUInt,
} from './reference-util.js';
import {
  fixedTypedVectorElementSize,
  fixedTypedVectorElementType,
  isAVector,
  isFixedTypedVector,
  isIndirectNumber,
  isNumber,
  isTypedVector,
  packedType,
  typedVectorElementType,
} from './value-type-util.js';
import {ValueType} from './value-type.js';

export function toReference(buffer: ArrayBuffer): Reference {
  const len = buffer.byteLength;

  if (len < 3) {
    throw new Error('Buffer needs to be bigger than 3 bytes');
  }

  const dataView = new DataView(buffer);
  const rootByteWidth = dataView.getUint8(len - 1);
  const packedType = dataView.getUint8(len - 2);

  let parentWidth = fromByteWidth(rootByteWidth);
  let offset = len - rootByteWidth - 2;

  const rootValueType = packedType >> 2;
  if (
    rootValueType === ValueType.VECTOR ||
    rootValueType === ValueType.MAP ||
    rootValueType === ValueType.BLOB ||
    rootValueType === ValueType.STRING
  ) {
    // Ensure parent width is wide enough to address the buffer
    let w = 1;
    while ((1 << (w * 8)) <= len && w < 8) w <<= 1;
    parentWidth = fromByteWidth(w);
    offset = len - w - 2; // no extra hacks
  }

  return new Reference(dataView, offset, parentWidth, packedType, '/');
}

function valueForIndexWithKey(
  index: number,
  key: string,
  dataView: DataView,
  offset: number,
  parentWidth: number,
  byteWidth: number,
  length: number,
  path: string,
): Reference {
  const _indirect = indirect(dataView, offset, parentWidth);
  const elementOffset = _indirect + index * byteWidth;
  const packedType = dataView.getUint8(_indirect + length * byteWidth + index);
  return new Reference(
    dataView,
    elementOffset,
    fromByteWidth(byteWidth),
    packedType,
    `${path}/${key}`,
  );
}

export class Reference {
  private readonly byteWidth: number;
  private readonly valueType: ValueType;
  private _length = -1;
  constructor(
    private dataView: DataView,
    private offset: number,
    private parentWidth: number,
    private packedType: ValueType,
    private path: string,
  ) {
    this.byteWidth = 1 << (packedType & 3);
    this.valueType = packedType >> 2;
  }

  isNull(): boolean {
    return this.valueType === ValueType.NULL;
  }
  isNumber(): boolean {
    return isNumber(this.valueType) || isIndirectNumber(this.valueType);
  }
  isFloat(): boolean {
    return (
      ValueType.FLOAT === this.valueType ||
      ValueType.INDIRECT_FLOAT === this.valueType
    );
  }
  isInt(): boolean {
    return this.isNumber() && !this.isFloat();
  }
  isString(): boolean {
    return (
      ValueType.STRING === this.valueType || ValueType.KEY === this.valueType
    );
  }
  isBool(): boolean {
    return ValueType.BOOL === this.valueType;
  }
  isBlob(): boolean {
    return ValueType.BLOB === this.valueType;
  }
  isVector(): boolean {
    return isAVector(this.valueType);
  }
  isMap(): boolean {
    return ValueType.MAP === this.valueType;
  }

  boolValue(): boolean | null {
    if (this.isBool()) {
      return readInt(this.dataView, this.offset, this.parentWidth) > 0;
    }
    return null;
  }

  intValue(): number | bigint | null {
    if (this.valueType === ValueType.INT) {
      return readInt(this.dataView, this.offset, this.parentWidth);
    }
    if (this.valueType === ValueType.UINT) {
      return readUInt(this.dataView, this.offset, this.parentWidth);
    }
    if (this.valueType === ValueType.INDIRECT_INT) {
      return readInt(
        this.dataView,
        indirect(this.dataView, this.offset, this.parentWidth),
        fromByteWidth(this.byteWidth),
      );
    }
    if (this.valueType === ValueType.INDIRECT_UINT) {
      return readUInt(
        this.dataView,
        indirect(this.dataView, this.offset, this.parentWidth),
        fromByteWidth(this.byteWidth),
      );
    }
    return null;
  }

  floatValue(): number | null {
    if (this.valueType === ValueType.FLOAT) {
      return readFloat(this.dataView, this.offset, this.parentWidth);
    }
    if (this.valueType === ValueType.INDIRECT_FLOAT) {
      return readFloat(
        this.dataView,
        indirect(this.dataView, this.offset, this.parentWidth),
        fromByteWidth(this.byteWidth),
      );
    }
    return null;
  }

  numericValue(): number | bigint | null {
    return this.floatValue() || this.intValue();
  }

  stringValue(): string | null {
    if (
      this.valueType === ValueType.STRING ||
      this.valueType === ValueType.KEY
    ) {
      const begin = indirect(this.dataView, this.offset, this.parentWidth);
      return fromUTF8Array(
        new Uint8Array(this.dataView.buffer, begin, this.length()),
      );
    }
    return null;
  }

  blobValue(): Uint8Array | null {
    if (this.isBlob()) {
      const begin = indirect(this.dataView, this.offset, this.parentWidth);
      return new Uint8Array(this.dataView.buffer, begin, this.length());
    }
    return null;
  }

  get(key: number): Reference {
    const length = this.length();
    if (Number.isInteger(key) && isAVector(this.valueType)) {
      if (key >= length || key < 0) {
        throw new Error(`Key: [${key}] is not applicable on ${this.path} of ${this.valueType} length: ${length}`);
      }
      const _indirect = indirect(this.dataView, this.offset, this.parentWidth);
      const elementOffset = _indirect + key * this.byteWidth;

      let _packedType: ValueType;

      if (isTypedVector(this.valueType)) {
      // Root typed vector: derive type instead of reading from buffer
      const _valueType = typedVectorElementType(this.valueType);
      _packedType = packedType(_valueType, BitWidth.WIDTH8);
    } else if (isFixedTypedVector(this.valueType)) {
      const _valueType = fixedTypedVectorElementType(this.valueType);
      _packedType = packedType(_valueType, BitWidth.WIDTH8);
    } else {
      // Only read packed type from buffer if it exists
      const typeOffset = _indirect + length * this.byteWidth + key;
      if (typeOffset < this.dataView.byteLength) {
        _packedType = this.dataView.getUint8(typeOffset);
      } else {
        // fallback for edge cases (e.g., root vectors)
        _packedType = this.packedType;
      }
      }

      return new Reference(
        this.dataView,
        elementOffset,
        fromByteWidth(this.byteWidth),
        _packedType,
        `${this.path}[${key}]`,
      );
    }

    if (typeof key === 'string') {
      const index = keyIndex(
        key,
        this.dataView,
        this.offset,
        this.parentWidth,
        this.byteWidth,
        length,
      );
      if (index !== null) {
        return valueForIndexWithKey(
          index,
          key,
          this.dataView,
          this.offset,
          this.parentWidth,
          this.byteWidth,
          length,
          this.path,
        );
      }
    }

    throw new Error(`Key [${key}] is not applicable on ${this.path} of ${this.valueType}`);
  }

  length(): number {
    let size;
    if (this._length > -1) {
      return this._length;
    }
    if (isFixedTypedVector(this.valueType)) {
      this._length = fixedTypedVectorElementSize(this.valueType);
    } else if (
      this.valueType === ValueType.BLOB ||
      this.valueType === ValueType.MAP ||
      isAVector(this.valueType)
    ) {
      this._length = readUInt(
        this.dataView,
        indirect(this.dataView, this.offset, this.parentWidth) - this.byteWidth,
        fromByteWidth(this.byteWidth),
      ) as number;
    } else if (this.valueType === ValueType.NULL) {
      this._length = 0;
    } else if (this.valueType === ValueType.STRING) {
      const _indirect = indirect(this.dataView, this.offset, this.parentWidth);
      let sizeByteWidth = this.byteWidth;
      size = readUInt(
        this.dataView,
        _indirect - sizeByteWidth,
        fromByteWidth(this.byteWidth),
      );
      while (this.dataView.getInt8(_indirect + (size as number)) !== 0) {
        sizeByteWidth <<= 1;
        size = readUInt(
          this.dataView,
          _indirect - sizeByteWidth,
          fromByteWidth(this.byteWidth),
        );
      }
      this._length = size as number;
    } else if (this.valueType === ValueType.KEY) {
      const _indirect = indirect(this.dataView, this.offset, this.parentWidth);
      size = 1;
      while (this.dataView.getInt8(_indirect + size) !== 0) {
        size++;
      }
      this._length = size;
    } else {
      this._length = 1;
    }
    return Number(this._length);
  }

  toObject(): unknown {
    const length = this.length();
    if (this.isVector()) {
      const result = [];
      for (let i = 0; i < length; i++) {
        result.push(this.get(i).toObject());
      }
      return result;
    }
    if (this.isMap()) {
      const result: Record<string, unknown> = {};
      for (let i = 0; i < length; i++) {
        const key = keyForIndex(
          i,
          this.dataView,
          this.offset,
          this.parentWidth,
          this.byteWidth,
        );
        result[key] = valueForIndexWithKey(
          i,
          key,
          this.dataView,
          this.offset,
          this.parentWidth,
          this.byteWidth,
          length,
          this.path,
        ).toObject();
      }
      return result;
    }
    if (this.isNull()) {
      return null;
    }
    if (this.isBool()) {
      return this.boolValue();
    }
    if (this.isNumber()) {
      return this.numericValue();
    }
    return this.blobValue() || this.stringValue();
  }
}
