// 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.

import 'dart:async';
import 'dart:io';
import 'dart:isolate';

import 'package:logging/logging.dart';
import 'package:meta/meta.dart';

import '_log_message.dart';

const int _maxGlobalTags = 4; // leave one slot for code location
const int _maxTagLength = 63;

final _fileNameRegex = RegExp(r'(\w+\.dart)');
final _lineNumberRegex = RegExp(r'\.dart:(\d+)');

/// The base class for which log writers will inherit from. This class is
/// used to pipe logs from the onRecord stream
abstract class LogWriter {
  List<String> _globalTags = const [];

  StreamController<LogMessage> _controller;

  /// If set to true, this method will include the stack trace
  /// in each log record so we can later extract out the call site.
  /// This is a heavy operation and should be used with caution.
  bool forceShowCodeLocation = false;

  /// Constructor
  LogWriter({
    @required Logger logger,
    bool shouldBufferLogs = false,
  }) : assert(logger != null) {
    void Function(LogMessage) onMessageFunc;

    if (shouldBufferLogs) {
      // create single subscription stream controller so that we buffer calls to the
      // stream while we connect to the logger. This avoids dropping logs that
      // come in while we wait.
      _controller = StreamController<LogMessage>();

      onMessageFunc = _controller.add;
    } else {
      onMessageFunc = onMessage;
    }
    logger.onRecord.listen(
        (record) => onMessageFunc(_messageFromRecord(record)),
        onDone: () => _controller?.close());
  }

  /// The global tags to add to each log record.
  set globalTags(List<String> tags) => _globalTags = _verifyGlobalTags(tags);

  /// Remaps the level string to the ones used in FTL.
  String getLevelString(Level level) {
    if (level == null) {
      return null;
    }

    if (level == Level.FINE) {
      return 'VLOG(1)';
    } else if (level == Level.FINER) {
      return 'VLOG(2)';
    } else if (level == Level.FINEST) {
      return 'VLOG(3)';
    } else if (level == Level.SEVERE) {
      return 'ERROR';
    } else if (level == Level.SHOUT) {
      return 'FATAL';
    } else {
      return level.toString();
    }
  }

  LogMessage _messageFromRecord(LogRecord record) => LogMessage(
        record: record,
        processId: pid,
        threadId: Isolate.current.hashCode,
        tags: _tagsForLogMessage(),
      );

  /// A method for subclasses to implement to handle messages as they are
  /// written
  void onMessage(LogMessage message);

  /// A method which is exposed to subclasses which can be used to indicate that
  /// they are ready to start receiving messages.
  @protected
  void startListening(void Function(LogMessage) onMessage) =>
      _controller.stream.listen(onMessage);

  List<String> _verifyGlobalTags(List<String> tags) {
    List<String> result = <String>[];

    // make our own copy to allow us to remove null values an not change the
    // original values
    final incomingTags = List.of(tags)
      ..removeWhere((t) => t == null || t.isEmpty);

    if (incomingTags != null) {
      if (incomingTags.length > _maxGlobalTags) {
        Logger.root.warning('Logger initialized with > $_maxGlobalTags tags.');
        Logger.root.warning('Later tags will be ignored.');
      }
      for (int i = 0; i < _maxGlobalTags && i < incomingTags.length; i++) {
        String s = incomingTags[i];
        if (s.length > _maxTagLength) {
          Logger.root
              .warning('Logger tags limited to $_maxTagLength characters.');
          Logger.root.warning('Tag "$s" will be truncated.');
          s = s.substring(0, _maxTagLength);
        }
        result.add(s);
      }
    }
    return result;
  }

  List<String> _tagsForLogMessage() {
    if (forceShowCodeLocation) {
      final codeLocation = _codeLocationFromStackTrace(StackTrace.current);
      if (codeLocation != null && codeLocation.isNotEmpty) {
        return List.of(_globalTags)..add(codeLocation);
      }
    }
    return _globalTags;
  }

  String _codeLocationFromStackTrace(StackTrace stackTrace) {
    final lines = stackTrace.toString().split('\n');
    // There is no well supported way for getting the calling code location from
    // the log line. In lieu of this, we use the following algorithm which is
    // fragile and depends on the order which the logger methods are called. The
    // algorithm is that we run through each line and look for the call to the
    // line that contains 'Logger.log (package:logging/logging.dart' which is
    // the call that comes after the user calls Logger.info, Logger.warn, etc.
    // When this line is found we look 2 lines past for their call site.

    const loggerLogLine = r'Logger.log (package:logging/logging.dart';
    const logLineOffset = 2;
    String codeLocation;

    for (int lineNumber = 0; lineNumber < lines.length; lineNumber++) {
      final line = lines[lineNumber];
      if (line.contains(loggerLogLine)) {
        if (lineNumber + logLineOffset < lines.length) {
          codeLocation = lines[lineNumber + logLineOffset];
        }
        break;
      }
    }

    return _extractCodeLocationFromLine(codeLocation);
  }

  String _extractCodeLocationFromLine(String line) {
    if (line == null) {
      return null;
    }

    String regexValue(RegExp regexp) {
      final match = regexp.firstMatch(line);
      return match != null ? match.group(1) : null;
    }

    final fileName = regexValue(_fileNameRegex);
    if (fileName == null) {
      return null;
    }

    final lineNumber = regexValue(_lineNumberRegex);

    // Some environments don't give us the line number so we avoid failing
    // completely if we have just the file name.
    return lineNumber == null ? fileName : '$fileName($lineNumber)';
  }
}
