// Copyright (c) 2022, 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.

// ignore_for_file: prefer_interpolation_to_compose_strings
// ignore_for_file: unnecessary_string_interpolations

import 'dart:typed_data';

import 'package:vm_service/vm_service.dart';

import 'analysis.dart';

String format(int a) => a.toString().padLeft(6, ' ');
String formatBytes(int a) => (a ~/ 1024).toString().padLeft(6, ' ') + ' kb';
String truncateString(String s) {
  int index;

  index = s.indexOf('\n');
  if (index >= 0) s = s.substring(index);

  index = s.indexOf('\r');
  if (index >= 0) s = s.substring(index);

  if (s.length > 30) s = s.substring(30);
  return s;
}

String formatHeapStats(HeapStats stats, {int? maxLines, int? sizeCutoff}) {
  assert(sizeCutoff == null || sizeCutoff >= 0);
  assert(maxLines == null || maxLines >= 0);

  final table = Table();
  table.addRow(['size', 'count', 'class']);
  table.addRow(['--------', '--------', '--------']);
  int totalSize = 0;
  int totalCount = 0;
  for (int i = 0; i < stats.classes.length; ++i) {
    final c = stats.classes[i];
    final count = stats.counts[c.classId];
    final size = stats.sizes[c.classId];

    totalSize += size;
    totalCount += count;

    if (sizeCutoff == null || size >= sizeCutoff) {
      if (maxLines == null || i < maxLines) {
        table.addRow(
            [formatBytes(size), format(count), '${c.name} ${c.libraryUri}']);
      }
    }
  }
  if (table.rows > 3) {
    table.addRow(['--------', '--------']);
    table.addRow([formatBytes(totalSize), format(totalCount)]);
  }
  return table.asString;
}

String formatDataStats(HeapDataStats stats, {int? maxLines, int? sizeCutoff}) {
  assert(sizeCutoff == null || sizeCutoff >= 0);
  assert(maxLines == null || maxLines >= 0);

  final table = Table();
  table.addRow(['size', 'unique-size', 'count', 'class', 'data']);
  table.addRow(['--------', '--------', '--------', '--------', '--------']);

  int totalSize = 0;
  int totalUniqueSize = 0;
  int totalCount = 0;

  final List<HeapData> datas = stats.datas;
  for (int i = 0; i < datas.length; ++i) {
    final data = datas[i];

    totalSize += data.size;
    totalUniqueSize += data.totalSize;
    totalCount += data.count;

    if (sizeCutoff == null || data.totalSize >= sizeCutoff) {
      if (maxLines == null || i < maxLines) {
        table.addRow([
          formatBytes(data.totalSize),
          formatBytes(data.size),
          format(data.count),
          data.klass,
          data.valueAsString,
        ]);
      }
    }
  }
  if (table.rows > 3) {
    table.addRow(['--------', '--------', '--------']);
    table.addRow([
      formatBytes(totalUniqueSize),
      formatBytes(totalSize),
      format(totalCount)
    ]);
  }
  return table.asString;
}

String formatRetainingPath(HeapSnapshotGraph graph, DedupedUint32List rpath) {
  final path = _stringifyRetainingPath(graph, rpath);
  final bool wasTruncated = rpath.path.last != /*root*/ 1;
  final sb = StringBuffer();
  for (int i = 0; i < path.length; ++i) {
    final indent = i >= 2 ? (i - 1) : 0;
    sb.writeln(' ' * 4 * indent + (i == 0 ? '' : '⮑ ') + '${path[i]}');
  }
  if (wasTruncated) {
    sb.writeln(' ' * 4 * (path.length - 1) + '⮑  …');
  }
  return sb.toString();
}

String formatDominatorPath(HeapSnapshotGraph graph, DedupedUint32List dpath) {
  final path = _stringifyDominatorPath(graph, dpath);
  final bool wasTruncated = dpath.path.last != /*root*/ 1;
  final sb = StringBuffer();
  for (int i = 0; i < path.length; ++i) {
    final indent = i >= 2 ? (i - 1) : 0;
    sb.writeln(' ' * 4 * indent + (i == 0 ? '' : '⮑  ') + '${path[i]}');
  }
  if (wasTruncated) {
    sb.writeln(' ' * 4 * (path.length - 1) + '⮑  …');
  }
  return sb.toString();
}

List<String> _stringifyRetainingPath(
    HeapSnapshotGraph graph, DedupedUint32List rpath) {
  final path = rpath.path;
  final spath = <String>[];
  for (int i = 0; i < path.length; i += 2) {
    final klass = graph.classes[path[i]];

    String? fieldName;
    String prefix = '';
    if (i > 0) {
      final int value = path[i - 1];
      final hasUniqueOwner = (value & (1 << 0)) == 1;
      final fieldIndex = value >> 1;
      if (fieldIndex != DedupedUint32List.noFieldIndex) {
        final field = klass.fields[fieldIndex];
        assert(field.index == fieldIndex);
        fieldName = field.name;
      }
      prefix = (hasUniqueOwner ? '・' : '﹢');
    }

    spath.add(prefix +
        '${klass.name}' +
        (fieldName != null ? '.$fieldName' : '') +
        ' (${klass.libraryUri})');
  }
  return spath;
}

List<String> _stringifyDominatorPath(
    HeapSnapshotGraph graph, DedupedUint32List rpath) {
  final path = rpath.path;
  final spath = <String>[];
  for (int i = 0; i < path.length; i++) {
    final klass = graph.classes[path[i]];
    spath.add('${klass.name} (${klass.libraryUri})');
  }
  return spath;
}

class Table {
  final List<List<String>> _rows = [];
  int _maxColumn = -1;

  int get rows => _rows.length;

  void addRow(List<String> row) {
    _maxColumn = row.length > _maxColumn ? row.length : _maxColumn;
    _rows.add(row);
  }

  String get asString {
    if (_rows.isEmpty) return '';

    final colSizes = Uint32List(_maxColumn);
    for (final row in _rows) {
      for (int i = 0; i < row.length; ++i) {
        final value = row[i];
        final c = colSizes[i];
        if (value.length > c) colSizes[i] = value.length;
      }
    }

    final sb = StringBuffer();
    for (final row in _rows) {
      for (int i = 0; i < row.length; ++i) {
        row[i] = row[i].padRight(colSizes[i], ' ');
      }
      sb.writeln(row.join('  '));
    }
    return sb.toString().trimRight();
  }
}

String indent(String left, String text) {
  return left + text.replaceAll('\n', '\n$left');
}
