// 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/assert';
import {isString} from '../base/object_utils';

// 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 (isString(token)) {
    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 (isString(token)) {
    // 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);
  }
}
