// 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 = new 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 = new 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)
      : new 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));
}
