// Copyright (c) 2020, 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 'dart:math' as math;

enum SortOrder {
  /// From fewest occurrences to most.
  ascending,

  /// From most occurrences to fewest.
  descending,

  /// Lexicographically sorted by name.
  alphabetical,

  /// Keys are parsed as integers and sorted by value.
  numeric,
}

/// Counts occurrences of strings and displays the results as a histogram.
class Histogram {
  final Map<Object, int> _counts = {};
  final SortOrder _order;
  final bool _showBar;
  final bool _showAll;
  final int _minCount;

  int get totalCount => _counts.values.fold(0, (a, b) => a + b);

  Histogram({SortOrder? order, bool? showBar, bool? showAll, int? minCount})
      : _order = order ?? SortOrder.descending,
        _showBar = showBar ?? true,
        _showAll = showAll ?? false,
        _minCount = minCount ?? 0;

  void add(Object item) {
    _counts.putIfAbsent(item, () => 0);
    _counts[item] = _counts[item]! + 1;
  }

  void printCounts(String label) {
    var total = totalCount;
    print('');
    print('-- $label ($total total) --');

    var keys = _counts.keys.toList();
    switch (_order) {
      case SortOrder.ascending:
        keys.sort((a, b) => _counts[a]!.compareTo(_counts[b]!));
        break;
      case SortOrder.descending:
        keys.sort((a, b) => _counts[b]!.compareTo(_counts[a]!));
        break;
      case SortOrder.alphabetical:
        keys.sort();
        break;
      case SortOrder.numeric:
        // TODO(rnystrom): Using string keys but treating them as integers is
        // kind of hokey. But it keeps the [ScrapeVisitor] API simpler.
        keys.sort((a, b) => (a as int).compareTo(b as int));
        break;
    }

    var longest = keys.fold<int>(
        0, (length, key) => math.max(length, key.toString().length));
    var barScale = 80 - 22 - longest;

    var shown = 0;
    var skipped = 0;
    for (var object in keys) {
      var count = _counts[object]!;
      var countString = count.toString().padLeft(7);
      var percent = 100 * count / total;
      var percentString = percent.toStringAsFixed(3).padLeft(7);

      if (_showAll || ((shown < 100 || percent >= 0.1) && count >= _minCount)) {
        var line = '$countString ($percentString%): $object';
        if (_showBar && barScale > 1) {
          line = line.padRight(longest + 22);
          line += '=' * (percent / 100 * barScale).ceil();
        }
        print(line);
        shown++;
      } else {
        skipped++;
      }
    }

    if (skipped > 0) print('And $skipped more...');

    // If we're counting numeric keys, show other statistics too.
    if (_order == SortOrder.numeric && keys.isNotEmpty) {
      var sum = keys.fold<int>(
          0, (result, key) => result + (key as int) * _counts[key]!);
      var average = sum / total;

      // Find the median key where half the total count is below it.
      var count = 0;
      var median = -1;
      for (var key in keys) {
        count += _counts[key]!;
        if (count >= total ~/ 2) {
          median = key as int;
          break;
        }
      }

      print('Sum $sum, average ${average.toStringAsFixed(3)}, median $median');
    }
  }
}
