// Copyright (C) 2022 The Android Open Source Project
//
// Licensed 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 {
  length as utf8Len,
  write as utf8Write,
} from '@protobufjs/utf8';

import {assertTrue} from '../base/logging';

// A token that can be appended to an `ArrayBufferBuilder`.
export type ArrayBufferToken = string|number|Uint8Array;

// Return the length, in bytes, of a token to be inserted.
function tokenLength(token: ArrayBufferToken): number {
  if (typeof token === 'string') {
    return utf8Len(token);
  } else if (token instanceof Uint8Array) {
    return token.byteLength;
  } else {
    assertTrue(token >= 0 && token <= 0xffffffff);
    // 32-bit integers take 4 bytes
    return 4;
  }
}

// Insert a token into the buffer, at position `byteOffset`.
//
// @param dataView A DataView into the buffer to write into.
// @param typedArray A Uint8Array view into the buffer to write into.
// @param byteOffset Position to write at, in the buffer.
// @param token Token to insert into the buffer.
function insertToken(
    dataView: DataView,
    typedArray: Uint8Array,
    byteOffset: number,
    token: ArrayBufferToken): void {
  if (typeof token === 'string') {
    // Encode the string in UTF-8
    const written = utf8Write(token, typedArray, byteOffset);
    assertTrue(written === utf8Len(token));
  } else if (token instanceof Uint8Array) {
    // Copy the bytes from the other array
    typedArray.set(token, byteOffset);
  } else {
    assertTrue(token >= 0 && token <= 0xffffffff);
    // 32-bit little-endian value
    dataView.setUint32(byteOffset, token, true);
  }
}

// Like a string builder, but for an ArrayBuffer instead of a string. This
// allows us to assemble messages to send/receive over the wire. Data can be
// appended to the buffer using `append()`. The data we append can be of the
// following types:
//
// - string: the ASCII string is appended. Throws an error if there are
//           non-ASCII characters.
// - number: the number is appended as a 32-bit little-endian integer.
// - Uint8Array: the bytes are appended as-is to the buffer.
export class ArrayBufferBuilder {
  private readonly tokens: ArrayBufferToken[] = [];

  // Return an `ArrayBuffer` that is the concatenation of all the tokens.
  toArrayBuffer(): ArrayBuffer {
    // Calculate the size of the buffer we need.
    let byteLength = 0;
    for (const token of this.tokens) {
      byteLength += tokenLength(token);
    }
    // Allocate the buffer.
    const buffer = new ArrayBuffer(byteLength);
    const dataView = new DataView(buffer);
    const typedArray = new Uint8Array(buffer);
    // Fill the buffer with the tokens.
    let byteOffset = 0;
    for (const token of this.tokens) {
      insertToken(dataView, typedArray, byteOffset, token);
      byteOffset += tokenLength(token);
    }
    assertTrue(byteOffset === byteLength);
    // Return the values.
    return buffer;
  }

  // Add one or more tokens to the value of this object.
  append(token: ArrayBufferToken): void {
    this.tokens.push(token);
  }
}
