// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:path/path.dart' as p;

import 'resolver.dart';

abstract class Formatter {
  /// Returns the formatted coverage data.
  Future<String> format(Map<String, Map<int, int>> hitmap);
}

/// Converts the given hitmap to lcov format and appends the result to
/// env.output.
///
/// Returns a [Future] that completes as soon as all map entries have been
/// emitted.
class LcovFormatter implements Formatter {
  /// Creates a LCOV formatter.
  ///
  /// If [reportOn] is provided, coverage report output is limited to files
  /// prefixed with one of the paths included. If [basePath] is provided, paths
  /// are reported relative to that path.
  LcovFormatter(this.resolver, {this.reportOn, this.basePath});

  final Resolver resolver;
  final String? basePath;
  final List<String>? reportOn;

  @override
  Future<String> format(Map<String, Map<int, int>> hitmap) async {
    final pathFilter = _getPathFilter(reportOn);
    final buf = StringBuffer();
    for (var key in hitmap.keys) {
      final v = hitmap[key]!;
      var source = resolver.resolve(key);
      if (source == null) {
        continue;
      }

      if (!pathFilter(source)) {
        continue;
      }

      if (basePath != null) {
        source = p.relative(source, from: basePath);
      }

      buf.write('SF:$source\n');
      final lines = v.keys.toList()..sort();
      for (var k in lines) {
        buf.write('DA:$k,${v[k]}\n');
      }
      buf.write('LF:${lines.length}\n');
      buf.write('LH:${lines.where((k) => v[k]! > 0).length}\n');
      buf.write('end_of_record\n');
    }

    return buf.toString();
  }
}

/// Converts the given hitmap to a pretty-print format and appends the result
/// to env.output.
///
/// Returns a [Future] that completes as soon as all map entries have been
/// emitted.
class PrettyPrintFormatter implements Formatter {
  /// Creates a pretty-print formatter.
  ///
  /// If [reportOn] is provided, coverage report output is limited to files
  /// prefixed with one of the paths included.
  PrettyPrintFormatter(this.resolver, this.loader, {this.reportOn});

  final Resolver resolver;
  final Loader loader;
  final List<String>? reportOn;

  @override
  Future<String> format(Map<String, dynamic> hitmap) async {
    final pathFilter = _getPathFilter(reportOn);
    final buf = StringBuffer();
    for (var key in hitmap.keys) {
      final v = hitmap[key] as Map<int, int>;
      final source = resolver.resolve(key);
      if (source == null) {
        continue;
      }

      if (!pathFilter(source)) {
        continue;
      }

      final lines = await loader.load(source);
      if (lines == null) {
        continue;
      }
      buf.writeln(source);
      for (var line = 1; line <= lines.length; line++) {
        var prefix = _prefix;
        if (v.containsKey(line)) {
          prefix = v[line].toString().padLeft(_prefix.length);
        }
        buf.writeln('$prefix|${lines[line - 1]}');
      }
    }

    return buf.toString();
  }
}

const _prefix = '       ';

typedef _PathFilter = bool Function(String path);

_PathFilter _getPathFilter(List<String>? reportOn) {
  if (reportOn == null) return (String path) => true;

  final absolutePaths = reportOn.map(p.absolute).toList();
  return (String path) => absolutePaths.any((item) => path.startsWith(item));
}
