// Copyright (C) 2021 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 protobuf from 'protobufjs/minimal';
import {assertTrue} from '../base/logging';

import {ProtoRingBuffer} from './proto_ring_buffer';

let seed = 1;

// For reproducibility.
function Rnd(max: number) {
  seed = seed * 16807 % 2147483647;
  return seed % max;
}

function MakeProtoMessage(fieldId: number, len: number) {
  const writer = protobuf.Writer.create();
  const tag = (fieldId << 3) | 2;
  assertTrue(tag < 0x80 && (tag & 7) === 2);
  writer.uint32(tag);
  const data = new Uint8Array(len);
  for (let i = 0; i < len; i++) {
    data[i] = 48 + ((fieldId + i) % 73);
  }
  writer.bytes(data);
  const res = writer.finish();
  // For whatever reason the object returned by protobufjs' Writer cannot be
  // directly .toEqual()-ed with Uint8Arrays.
  const buf = new Uint8Array(res.length);
  buf.set(res);
  return buf;
}

test('ProtoRingBufferTest.Fastpath', () => {
  const buf = new ProtoRingBuffer();

  for (let rep = 0; rep < 3; rep++) {
    let inputBuf = MakeProtoMessage(1, 32);
    buf.append(inputBuf);
    let msg = buf.readMessage();
    expect(msg).toBeDefined();
    expect(msg).toBeInstanceOf(Uint8Array);
    expect(msg!.length).toBe(32);

    // subarray(2) is to strip the proto preamble. The returned buffer starts at
    // the start of the payload.
    expect(msg).toEqual(inputBuf.subarray(2));

    // When we hit the fastpath, the returned message should be a subarray of
    // the same ArrayBuffer passed to append.
    expect(msg!.buffer).toBe(inputBuf.buffer);

    inputBuf = MakeProtoMessage(2, 32);
    buf.append(inputBuf.subarray(0, 13));
    expect(buf.readMessage()).toBeUndefined();
    buf.append(inputBuf.subarray(13));
    msg = buf.readMessage();
    expect(msg).toBeDefined();
    expect(msg).toBeInstanceOf(Uint8Array);
    expect(msg).toEqual(inputBuf.subarray(2));
    expect(msg!.buffer !== inputBuf.buffer).toBeTruthy();
  }
});

test('ProtoRingBufferTest.CoalescingStream', () => {
  const buf = new ProtoRingBuffer();

  const mergedBuf = new Uint8Array(612);
  const expected = new Array<Uint8Array>();
  for (let i = 1, pos = 0; i <= 6; i++) {
    const msg = MakeProtoMessage(i, 100);
    expected.push(msg);
    mergedBuf.set(msg, pos);
    pos += msg.length;
  }

  const fragLens = [120, 20, 471, 1];
  let fragSum = 0;
  fragLens.map((fragLen) => {
    buf.append(mergedBuf.subarray(fragSum, fragSum + fragLen));
    fragSum += fragLen;
    for (;;) {
      const msg = buf.readMessage();
      if (msg === undefined) break;
      const exp = expected.shift();
      expect(exp).toBeDefined();
      expect(msg).toEqual(exp!.subarray(-1 * msg.length));
    }
  });
  expect(expected.length).toEqual(0);
});


test('ProtoRingBufferTest.RandomSizes', () => {
  const buf = new ProtoRingBuffer();
  const kNumMsg = 100;
  const mergedBuf = new Uint8Array(1024 * 1024 * 32);
  const expectedLengths = [];
  let mergedLen = 0;
  for (let i = 0; i < kNumMsg; i++) {
    const fieldId = 1 + Rnd(15);  // We support only one byte tag.
    const rndVal = Rnd(1024);
    let len = 1 + rndVal;
    if ((rndVal % 100) < 5) {
      len *= 1000;
    }
    const msg = MakeProtoMessage(fieldId, len);
    assertTrue(mergedBuf.length >= mergedLen + msg.length);
    expectedLengths.push(len);
    mergedBuf.set(msg, mergedLen);
    mergedLen += msg.length;
  }

  for (let fragSum = 0; fragSum < mergedLen; /**/) {
    let fragLen = 1 + Rnd(1024 * 32);
    fragLen = Math.min(fragLen, mergedLen - fragSum);
    buf.append(mergedBuf.subarray(fragSum, fragSum + fragLen));
    fragSum += fragLen;
    for (;;) {
      const msg = buf.readMessage();
      if (msg === undefined) break;
      const expLen = expectedLengths.shift();
      expect(expLen).toBeDefined();
      expect(msg.length).toEqual(expLen);
    }
  }
  expect(expectedLengths.length).toEqual(0);
});
