import { FILE_IDENTIFIER_LENGTH, SIZEOF_INT } from "./constants";
import { Long } from "./long";
import { int32, isLittleEndian, float32, float64 } from "./utils";
import { Offset, Table, IGeneratedObject } from "./types";
import { Encoding } from "./encoding";

export class ByteBuffer {
    private position_ = 0;
  
    /**
     * Create a new ByteBuffer with a given array of bytes (`Uint8Array`)
     */
    constructor(private bytes_: Uint8Array) { }
  
    /**
     * Create and allocate a new ByteBuffer with a given size.
     */
    static allocate(byte_size: number): ByteBuffer {
      return new ByteBuffer(new Uint8Array(byte_size));
    }
  
    clear(): void {
      this.position_ = 0;
    }
  
    /**
     * Get the underlying `Uint8Array`.
     */
    bytes(): Uint8Array {
      return this.bytes_;
    }
  
    /**
     * Get the buffer's position.
     */
    position(): number {
      return this.position_;
    }
  
    /**
     * Set the buffer's position.
     */
    setPosition(position: number): void {
      this.position_ = position;
    }
  
    /**
     * Get the buffer's capacity.
     */
    capacity(): number {
      return this.bytes_.length;
    }
  
    readInt8(offset: number): number {
      return this.readUint8(offset) << 24 >> 24;
    }
  
    readUint8(offset: number): number {
      return this.bytes_[offset];
    }
  
    readInt16(offset: number): number {
      return this.readUint16(offset) << 16 >> 16;
    }
  
    readUint16(offset: number): number {
      return this.bytes_[offset] | this.bytes_[offset + 1] << 8;
    }
  
    readInt32(offset: number): number {
      return this.bytes_[offset] | this.bytes_[offset + 1] << 8 | this.bytes_[offset + 2] << 16 | this.bytes_[offset + 3] << 24;
    }
  
    readUint32(offset: number): number {
      return this.readInt32(offset) >>> 0;
    }
  
    readInt64(offset: number): Long {
      return new Long(this.readInt32(offset), this.readInt32(offset + 4));
    }
  
    readUint64(offset: number): Long {
      return new Long(this.readUint32(offset), this.readUint32(offset + 4));
    }
  
    readFloat32(offset: number): number {
      int32[0] = this.readInt32(offset);
      return float32[0];
    }
  
    readFloat64(offset: number): number {
      int32[isLittleEndian ? 0 : 1] = this.readInt32(offset);
      int32[isLittleEndian ? 1 : 0] = this.readInt32(offset + 4);
      return float64[0];
    }
  
    writeInt8(offset: number, value: number): void {
      this.bytes_[offset] = value;
    }
  
    writeUint8(offset: number, value: number): void {
      this.bytes_[offset] = value;
    }
  
    writeInt16(offset: number, value: number): void {
      this.bytes_[offset] = value;
      this.bytes_[offset + 1] = value >> 8;
    }
  
    writeUint16(offset: number, value: number): void {
        this.bytes_[offset] = value;
        this.bytes_[offset + 1] = value >> 8;
    }
  
    writeInt32(offset: number, value: number): void {
      this.bytes_[offset] = value;
      this.bytes_[offset + 1] = value >> 8;
      this.bytes_[offset + 2] = value >> 16;
      this.bytes_[offset + 3] = value >> 24;
    }
  
    writeUint32(offset: number, value: number): void {
        this.bytes_[offset] = value;
        this.bytes_[offset + 1] = value >> 8;
        this.bytes_[offset + 2] = value >> 16;
        this.bytes_[offset + 3] = value >> 24;
    }
  
    writeInt64(offset: number, value: Long): void {
      this.writeInt32(offset, value.low);
      this.writeInt32(offset + 4, value.high);
    }
  
    writeUint64(offset: number, value: Long): void {
        this.writeUint32(offset, value.low);
        this.writeUint32(offset + 4, value.high);
    }
  
    writeFloat32(offset: number, value: number): void {
      float32[0] = value;
      this.writeInt32(offset, int32[0]);
    }
  
    writeFloat64(offset: number, value: number): void {
      float64[0] = value;
      this.writeInt32(offset, int32[isLittleEndian ? 0 : 1]);
      this.writeInt32(offset + 4, int32[isLittleEndian ? 1 : 0]);
    }
  
    /**
     * Return the file identifier.   Behavior is undefined for FlatBuffers whose
     * schema does not include a file_identifier (likely points at padding or the
     * start of a the root vtable).
     */
    getBufferIdentifier(): string {
      if (this.bytes_.length < this.position_ + SIZEOF_INT +
          FILE_IDENTIFIER_LENGTH) {
        throw new Error(
            'FlatBuffers: ByteBuffer is too short to contain an identifier.');
      }
      let result = "";
      for (let i = 0; i < FILE_IDENTIFIER_LENGTH; i++) {
        result += String.fromCharCode(
            this.readInt8(this.position_ + SIZEOF_INT + i));
      }
      return result;
    }
  
    /**
     * Look up a field in the vtable, return an offset into the object, or 0 if the
     * field is not present.
     */
    __offset(bb_pos: number, vtable_offset: number): Offset {
      const vtable = bb_pos - this.readInt32(bb_pos);
      return vtable_offset < this.readInt16(vtable) ? this.readInt16(vtable + vtable_offset) : 0;
    }
  
    /**
     * Initialize any Table-derived type to point to the union at the given offset.
     */
    __union(t: Table, offset: number): Table {
      t.bb_pos = offset + this.readInt32(offset);
      t.bb = this;
      return t;
    }
  
    /**
     * Create a JavaScript string from UTF-8 data stored inside the FlatBuffer.
     * This allocates a new string and converts to wide chars upon each access.
     *
     * To avoid the conversion to UTF-16, pass Encoding.UTF8_BYTES as
     * the "optionalEncoding" argument. This is useful for avoiding conversion to
     * and from UTF-16 when the data will just be packaged back up in another
     * FlatBuffer later on.
     *
     * @param offset
     * @param opt_encoding Defaults to UTF16_STRING
     */
    __string(offset: number, opt_encoding?: Encoding): string | Uint8Array {
      offset += this.readInt32(offset);
  
      const length = this.readInt32(offset);
      let result = '';
      let i = 0;
  
      offset += SIZEOF_INT;
  
      if (opt_encoding === Encoding.UTF8_BYTES) {
        return this.bytes_.subarray(offset, offset + length);
      }
  
      while (i < length) {
        let codePoint;
  
        // Decode UTF-8
        const a = this.readUint8(offset + i++);
        if (a < 0xC0) {
          codePoint = a;
        } else {
          const b = this.readUint8(offset + i++);
          if (a < 0xE0) {
            codePoint =
              ((a & 0x1F) << 6) |
              (b & 0x3F);
          } else {
            const c = this.readUint8(offset + i++);
            if (a < 0xF0) {
              codePoint =
                ((a & 0x0F) << 12) |
                ((b & 0x3F) << 6) |
                (c & 0x3F);
            } else {
              const d = this.readUint8(offset + i++);
              codePoint =
                ((a & 0x07) << 18) |
                ((b & 0x3F) << 12) |
                ((c & 0x3F) << 6) |
                (d & 0x3F);
            }
          }
        }
  
        // Encode UTF-16
        if (codePoint < 0x10000) {
          result += String.fromCharCode(codePoint);
        } else {
          codePoint -= 0x10000;
          result += String.fromCharCode(
            (codePoint >> 10) + 0xD800,
            (codePoint & ((1 << 10) - 1)) + 0xDC00);
        }
      }
  
      return result;
    }
  
    /**
     * Handle unions that can contain string as its member, if a Table-derived type then initialize it, 
     * if a string then return a new one
     * 
     * WARNING: strings are immutable in JS so we can't change the string that the user gave us, this 
     * makes the behaviour of __union_with_string different compared to __union
     */
    __union_with_string(o: Table | string, offset: number) : Table | string {
      if(typeof o === 'string') {
        return this.__string(offset) as string;
      } 
      return this.__union(o, offset);
    }
  
    /**
     * Retrieve the relative offset stored at "offset"
     */
    __indirect(offset: Offset): Offset {
      return offset + this.readInt32(offset);
    }
  
    /**
     * Get the start of data of a vector whose offset is stored at "offset" in this object.
     */
    __vector(offset: Offset): Offset {
      return offset + this.readInt32(offset) + SIZEOF_INT; // data starts after the length
    }
  
    /**
     * Get the length of a vector whose offset is stored at "offset" in this object.
     */
    __vector_len(offset: Offset): Offset {
      return this.readInt32(offset + this.readInt32(offset));
    }
  
    __has_identifier(ident: string): boolean {
      if (ident.length != FILE_IDENTIFIER_LENGTH) {
        throw new Error('FlatBuffers: file identifier must be length ' +
                        FILE_IDENTIFIER_LENGTH);
      }
      for (let i = 0; i < FILE_IDENTIFIER_LENGTH; i++) {
        if (ident.charCodeAt(i) != this.readInt8(this.position() + SIZEOF_INT + i)) {
          return false;
        }
      }
      return true;
    }
  
    /**
     * A helper function to avoid generated code depending on this file directly.
     */
    createLong(low: number, high: number): Long {
      return Long.create(low, high);
    }
  
    /**
     * A helper function for generating list for obj api
     */
    createScalarList(listAccessor: (i: number) => unknown, listLength: number) : unknown[] {
      const ret: unknown[] = [];
      for(let i = 0; i < listLength; ++i) {
        if(listAccessor(i) !== null) {
          ret.push(listAccessor(i));
        }
      }
  
      return ret;
    }
  
    /**
     * This function is here only to get around typescript type system
     */
    createStringList(listAccessor: (i: number) => unknown, listLength: number): unknown[] {
      return this.createScalarList(listAccessor, listLength);
    }
  
    /**
     * A helper function for generating list for obj api
     * @param listAccessor function that accepts an index and return data at that index
     * @param listLength listLength
     * @param res result list
     */
    createObjList(listAccessor: (i: number) => IGeneratedObject, listLength: number): IGeneratedObject[] {
      const ret: IGeneratedObject[] = [];
      for(let i = 0; i < listLength; ++i) {
        const val = listAccessor(i);
        if(val !== null) {
          ret.push(val.unpack());
        }
      }
      
      return ret;
    }
  
  }