// 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.
library vm_snapshot_analysis.utils;

import 'dart:io';
import 'dart:convert';

import 'package:vm_snapshot_analysis/ascii_table.dart';
import 'package:vm_snapshot_analysis/program_info.dart';
import 'package:vm_snapshot_analysis/instruction_sizes.dart'
    as instruction_sizes;
import 'package:vm_snapshot_analysis/treemap.dart';
import 'package:vm_snapshot_analysis/v8_profile.dart' as v8_profile;

Future<Object> loadJson(File input) async {
  return await input
      .openRead()
      .transform(utf8.decoder)
      .transform(json.decoder)
      .first;
}

Future<ProgramInfo> loadProgramInfo(File input,
    {bool collapseAnonymousClosures = false}) async {
  final json = await loadJson(input);
  if (v8_profile.Snapshot.isV8HeapSnapshot(json)) {
    return v8_profile.toProgramInfo(v8_profile.Snapshot.fromJson(json),
        collapseAnonymousClosures: collapseAnonymousClosures);
  } else {
    return instruction_sizes.loadProgramInfo(json,
        collapseAnonymousClosures: collapseAnonymousClosures);
  }
}

/// Compare two size profiles and return result of the comparison as a treemap.
Future<Map<String, dynamic>> buildComparisonTreemap(File oldJson, File newJson,
    {TreemapFormat format = TreemapFormat.collapsed,
    bool collapseAnonymousClosures = false}) async {
  final oldSizes = await loadProgramInfo(oldJson,
      collapseAnonymousClosures: collapseAnonymousClosures);
  final newSizes = await loadProgramInfo(newJson,
      collapseAnonymousClosures: collapseAnonymousClosures);

  final diff = computeDiff(oldSizes, newSizes);

  return treemapFromInfo(diff, format: format);
}

void printHistogram(ProgramInfo info, Histogram histogram,
    {Iterable<String> prefix = const [],
    Iterable<String> suffix = const [],
    String sizeHeader = 'Size (Bytes)',
    int maxWidth = 0}) {
  final totalSize = info.totalSize;
  final wasFiltered = totalSize != histogram.totalSize;
  final table = AsciiTable(header: [
    for (var col in histogram.bucketInfo.nameComponents) Text.left(col),
    Text.right(sizeHeader),
    Text.right('Percent'),
    if (wasFiltered) Text.right('Of total'),
  ], maxWidth: maxWidth);

  String formatPercent(int value, int total) {
    final p = value / total * 100.0;
    return p.toStringAsFixed(2) + "%";
  }

  if (prefix.isNotEmpty) {
    for (var key in prefix) {
      final size = histogram.buckets[key];
      table.addRow([
        ...histogram.bucketInfo.namesFromBucket(key),
        size.toString(),
        formatPercent(size, histogram.totalSize),
        if (wasFiltered) formatPercent(size, totalSize),
      ]);
    }
    table.addSeparator(
        prefix.length < histogram.length ? Separator.Wave : Separator.Line);
  }

  final visibleSize = [prefix, suffix]
      .expand((l) => l)
      .fold(0, (sum, key) => sum + histogram.buckets[key]);
  final numRestRows = histogram.length - (suffix.length + prefix.length);
  if (numRestRows > 0) {
    final totalRestBytes = histogram.totalSize - visibleSize;
    table.addTextSeparator(
        '$numRestRows more rows accounting for ${totalRestBytes}'
        ' (${formatPercent(totalRestBytes, totalSize)} of total) bytes');
    final avg = (totalRestBytes / numRestRows).round();
    table.addTextSeparator(
        'on average that is ${avg} (${formatPercent(avg, histogram.totalSize)})'
        ' bytes per row');
    table.addSeparator(suffix.isNotEmpty ? Separator.Wave : Separator.Line);
  }

  if (suffix.isNotEmpty) {
    for (var key in suffix) {
      table.addRow([
        ...histogram.bucketInfo.namesFromBucket(key),
        histogram.buckets[key].toString(),
        formatPercent(histogram.buckets[key], histogram.totalSize),
      ]);
    }
    table.addSeparator(Separator.Line);
  }

  table.render();

  if (wasFiltered || visibleSize != histogram.totalSize) {
    print('In visible rows: ${visibleSize}'
        ' (${formatPercent(visibleSize, totalSize)} of total)');
  }
  print('Total: ${totalSize} bytes');
}
