// Copyright 2018 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';
import 'dart:io';
import 'dart:typed_data';

import 'package:fuchsia_logger/src/internal/_log_message.dart';
import 'package:logging/logging.dart';
import 'package:test/test.dart';
import 'package:zircon/zircon.dart';

// 15 sec in nanoseconds
const int _lookBackTimeGap = 15 * 1000 * 1000 * 1000;
const int _socketBufferLength = 2032;
const int _zxClockMonotonic = 0;

void main() {
  /// the following tests are taken from the initial logging implementation.
  /// They should remain to ensure backwards compatibility
  group('legacy toBytes tests', () {
    test('convert to bytes info', () {
      final message = _makeMessage(Level.INFO, 'foo');

      final bytes = message.toBytes();
      final buffer = bytes.buffer.asUint8List();
      _validateFixedBlock(buffer, 0, 1, 2);

      expect(buffer[32], equals(4));
      expect(utf8.decode(buffer.sublist(33, 37)), equals('TEST'));
      expect(utf8.decode(buffer.sublist(38, 41)), equals('foo'));
      expect(buffer[41], equals(0));
      // Length should be 33 + 5 (TEST) + 4 (foo)
      expect(bytes.lengthInBytes, equals(42));
    });

    test('convert to bytes exception', () {
      final message =
          _makeMessage(Level.SHOUT, 'error', error: Exception('cause'));

      final bytes = message.toBytes();
      final buffer = bytes.buffer.asUint8List();
      _validateFixedBlock(buffer, 3, 1, 2);

      expect(buffer[32], equals(4));
      expect(utf8.decode(buffer.sublist(33, 37)), equals('TEST'));
      int end = 37;

      // dividing 0 byte
      expect(buffer[end++], equals(0));

      int start = end;
      expect(utf8.decode(buffer.sublist(start)),
          matches('error: Exception: cause'));
      end = start + 23;
      expect(buffer[end++], equals(0));
      expect(bytes.lengthInBytes, equals(end));
    });

    test('convert to bytes with stack trace', () {
      const errorMsg = 'this error message plus the stacktrace need to be '
          'long enough to hit the max block size to validate that truncation of long '
          'messages works properly';

      final message = _makeMessage(Level.SEVERE, errorMsg,
          error: Exception('because'),
          stackTrace:
              StackTrace.fromString('_STACK_START_ ${StackTrace.current}'));

      final bytes = message.toBytes();
      final buffer = bytes.buffer.asUint8List();
      _validateFixedBlock(buffer, 2, 1, 2);

      expect(buffer[32], equals(4));
      expect(utf8.decode(buffer.sublist(33, 37)), equals('TEST'));
      int end = 37;

      // dividing 0 byte
      expect(buffer[end++], equals(0));

      String msg = utf8.decode(buffer.sublist(end));
      expect(msg, startsWith('$errorMsg: Exception: because\n'));
      expect(msg, matches('_STACK_START_'));
      expect(buffer.length, equals(_socketBufferLength));
      expect(
          utf8.decode(
              buffer.sublist(_socketBufferLength - 4, _socketBufferLength - 1)),
          equals('...'));

      expect(bytes.lengthInBytes, _socketBufferLength);
    });

    test('convert to bytes with tags', () {
      final tags = ['tag1', 'tag2'];
      final message = _makeMessage(
        Level.FINE,
        'bar',
        tags: tags,
      );

      final bytes = message.toBytes();
      final buffer = bytes.buffer.asUint8List();
      _validateFixedBlock(buffer, -2, 1, 2);

      expect(buffer[32], equals(4));
      expect(utf8.decode(buffer.sublist(33, 37)), equals('TEST'));
      int start = 37;

      // verify the first tag
      expect(buffer[start], equals(tags[0].length));
      int end = start + buffer[start] + 1;
      start++;
      expect(utf8.decode(buffer.sublist(start, end)), equals(tags[0]));

      // verify the second tag
      start = end;
      expect(buffer[start], equals(tags[1].length));
      end = start + buffer[start] + 1;
      start++;
      expect(utf8.decode(buffer.sublist(start, end)), equals(tags[1]));

      // dividing 0 byte
      expect(buffer[end++], equals(0));

      start = end;
      expect(utf8.decode(buffer.sublist(start, start + 3)), equals('bar'));
      end = start + 3;
      expect(buffer[end++], equals(0));
      expect(bytes.lengthInBytes, equals(end));
    });
  });
}

List<String> _allTags(String name, List<String> tags) =>
    (name != null ? [name] : [])..addAll(tags ?? []);

/// Convert from little endian format bytes to an unsiged 32 bit int.
int _bytesToInt32(List<int> bytes) {
  ByteData byteData = ByteData(4);
  for (int i = 0; i < 4; i++) {
    byteData.setInt8(i, bytes[i]);
  }
  return byteData.getInt32(0, Endian.little);
}

/// Convert from little endian format bytes to an unsiged 64 bit int.
int _bytesToUint64(List<int> bytes) {
  ByteData byteData = ByteData(8);
  for (int i = 0; i < 8; i++) {
    byteData.setInt8(i, bytes[i]);
  }
  return byteData.getUint64(0, Endian.little);
}

LogMessage _makeMessage(Level level, String message,
        {int processId = 1,
        int threadId = 2,
        String name = 'TEST',
        Object error,
        StackTrace stackTrace,
        List<String> tags}) =>
    LogMessage(
      record: LogRecord(level, message, null, error, stackTrace),
      processId: processId,
      threadId: threadId,
      tags: _allTags(name, tags),
    );

void _validateFixedBlock(
    List<int> data, int level, int processId, int threadId) {
  expect(_bytesToUint64(data), equals(processId));
  expect(_bytesToUint64(data.sublist(8, 16)), equals(threadId));

  // Log time should be within the last 30 seconds
  int nowNanos = Platform.isFuchsia
      ? System.clockGet(_zxClockMonotonic)
      : DateTime.now().microsecondsSinceEpoch * 1000;
  int logNanos = _bytesToUint64(data.sublist(16, 24));

  expect(logNanos, lessThanOrEqualTo(nowNanos));
  expect(logNanos + _lookBackTimeGap, greaterThan(nowNanos));

  expect(_bytesToInt32(data.sublist(24, 28)), equals(level));
}
