// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// ignore_for_file: implementation_imports

import 'dart:convert' show Utf8Decoder;
import 'dart:typed_data';

import 'package:fidl_fuchsia_diagnostics_stream/fidl_async.dart';
import 'package:fidl_fuchsia_diagnostics/fidl_async.dart';
import 'package:test/test.dart';

import 'package:fuchsia_diagnostic_streams/src/internal/header.dart';
import 'package:fuchsia_diagnostic_streams/src/write.dart';

/// assert that buffer contains the serialized record.
void assertRecord(Record record, ByteData buffer) {
  var header = Header(buffer.getUint64(0, Endian.little));
  var timestamp = buffer.getInt64(8, Endian.little);

  expect(header.size, equals(buffer.lengthInBytes));
  expect(header.type, equals(9)); // log type

  List<Argument> arguments = [];
  var offset = 16;
  while (offset < buffer.lengthInBytes) {
    var parseResult = parseArgument(buffer, offset);
    arguments.add(parseResult.argument);
    offset = parseResult.nextOffset;
  }

  var foundRecord = Record(
      timestamp: timestamp,
      severity: Severity(header.severity),
      arguments: arguments);
  expect(foundRecord, equals(record));
}

class _ArgParseResult {
  final Argument argument;
  final int nextOffset;

  _ArgParseResult({this.argument, this.nextOffset});
}

/// parses an argument starting at the given offset.  Returns the found
/// argument and offset of the next entry.
_ArgParseResult parseArgument(ByteData buffer, int offset) {
  final header = Header(buffer.getUint64(offset, Endian.little));
  // Assume inline string reference for argument name. Last 15 bits are length.
  final nameLen = header.nameRef & 0x7fff;
  final padLen = (8 - (nameLen % 8)) % 8;
  final name =
      Utf8Decoder().convert(buffer.buffer.asInt8List(offset + 8, nameLen));

  final valuePos = offset + 8 + nameLen + padLen;
  Value value;
  var curOffset = valuePos;
  switch (header.type) {
    case tracingFormatI64Type:
      value = Value.withSignedInt(buffer.getInt64(valuePos, Endian.little));
      curOffset += 8;
      break;
    case tracingFormatU64Type: // unsigned int
      value = Value.withUnsignedInt(buffer.getUint64(valuePos, Endian.little));
      curOffset += 8;
      break;
    case tracingFormatF64Type: // floating point
      value = Value.withFloating(buffer.getFloat64(valuePos, Endian.little));
      curOffset += 8;
      break;
    case tracingFormatStringType: // string
      // Assume inline string reference for value.  Last 15 bits are length.
      final valLen = header.value & 0x7fff;
      final padLen = (8 - (valLen % 8)) % 8;
      final str =
          Utf8Decoder().convert(buffer.buffer.asInt8List(valuePos, valLen));
      value = Value.withText(str);
      curOffset += valLen + padLen;
      break;
    default:
      fail('Unrecognized header type ${header.type}');
  }

  expect(header.size, equals(curOffset - offset));
  return _ArgParseResult(
      argument: Argument(name: name, value: value), nextOffset: curOffset);
}

void testWriteRecord(Record record) {
  final bytes = ByteData(1024);
  final recordLen = writeRecord(bytes, record);
  assertRecord(record, bytes.buffer.asByteData(0, recordLen));
  expect(recordLen % 8, equals(0));
}

void testWriteArgument(Argument argument) {
  final bytes = ByteData(1024);
  final argLen = writeArgument(bytes, 0, argument);
  final argResult = parseArgument(bytes, 0);
  expect(argResult.argument, equals(argument));
  expect(argResult.nextOffset, equals(argLen));
  expect(argLen % 8, equals(0));
}

void main() {
  const int _testTimestamp = 23;
  group('write record tests', () {
    test('no arguments', () {
      testWriteRecord(Record(
          timestamp: _testTimestamp, severity: Severity.warn, arguments: []));
    });

    test('single argument', () {
      testWriteRecord(Record(
          timestamp: _testTimestamp,
          severity: Severity.info,
          arguments: [
            Argument(name: 'int-arg', value: Value.withSignedInt(2902))
          ]));
    });

    test('multiple arguments', () {
      final arguments = [
        Argument(name: '', value: Value.withText('')),
        Argument(name: 'arg-1', value: Value.withSignedInt(23)),
        Argument(name: 'arg-2', value: Value.withUnsignedInt(10)),
        Argument(name: 'arg-3', value: Value.withFloating(0.1)),
        Argument(name: 'arg-4', value: Value.withText('text'))
      ];
      testWriteRecord(Record(
          timestamp: _testTimestamp,
          severity: Severity.error,
          arguments: arguments));
    });
  });

  group('write argument tests', () {
    test('signed int', () {
      testWriteArgument(
          Argument(name: 'signed-arg', value: Value.withSignedInt(12)));
      testWriteArgument(
          Argument(name: 'signed-arg', value: Value.withSignedInt(-12)));
    });

    test('unsigned int', () {
      testWriteArgument(
          Argument(name: 'unsigned-arg', value: Value.withUnsignedInt(999)));
    });

    test('floating point', () {
      testWriteArgument(
          Argument(name: 'floating-arg', value: Value.withFloating(140.15)));
    });

    test('text', () {
      testWriteArgument(
          Argument(name: 'text-arg', value: Value.withText('arg-value')));
      testWriteArgument(Argument(name: 'text-arg', value: Value.withText('')));
    });
  });
}
