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

/// Generate a json file representing the files in the Dart SDK and their sizes.
/// Print out instructions for opening Dart DevTools to visualize this info.
library;

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

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

final String dartSdkPath = p.dirname(p.dirname(Platform.resolvedExecutable));

final List<FileStats> fileStats = [];

void main(List<String> arguments) {
  final version =
      File(p.join(dartSdkPath, 'version')).readAsStringSync().trim();

  final sdkData = build(Directory(dartSdkPath), extra: {
    'comment-1': 'Dart SDK $version',
    'comment-2': '<size>',
    'type': 'web',
  });
  final sdkSize = fileStats.fold<int>(0, (previous, e) => previous + e.size);

  sdkData['comment-2'] = sizeMB(sdkSize);
  final outFile = File('sdk-size.json');
  outFile.writeAsStringSync(JsonEncoder.withIndent('').convert(sdkData));

  const width = 52;

  print('Large SDK files');
  print('-----------------');
  fileStats.sort();
  for (var stat in fileStats) {
    if (stat.size < 2 * 1042 * 1024) break;

    print('${stat.path.padRight(width)}: ${sizeMB(stat.size)}');
  }

  print('');
  print('SDK: $dartSdkPath');
  print('Version: $version');
  print('Size: ${sizeMB(sdkSize)}');

  print('');
  print('Wrote data to ${outFile.path}; to view the SDK size treemap, run:');
  print('');
  print('  dart devtools --app-size-base=${outFile.path}');
  print('');
}

String sizeMB(int size) => '${(size / (1024.0 * 1024)).toStringAsFixed(1)}MB';

Map build(FileSystemEntity entity, {Map<String, String> extra = const {}}) {
  const fsBlockSize = 4096.0;

  if (entity is File) {
    final size =
        ((entity.lengthSync() / fsBlockSize).ceilToDouble() * fsBlockSize)
            .truncate();
    fileStats.add(FileStats(p.relative(entity.path, from: dartSdkPath), size));
    return {
      'n': entity.name,
      'value': size,
    };
  } else {
    entity as Directory;

    return {
      ...extra,
      'n': '${entity.name}/',
      'children': [
        ...entity.listSyncSorted().map(build),
      ],
    };
  }
}

extension FileSystemEntityExtension on FileSystemEntity {
  String get name => p.basename(path);
}

extension DirectoryExtension on Directory {
  List<FileSystemEntity> listSyncSorted() {
    return listSync()..sort((a, b) => a.name.compareTo(b.name));
  }
}

class FileStats implements Comparable<FileStats> {
  final String path;
  final int size;

  FileStats(this.path, this.size);

  @override
  int compareTo(FileStats other) => other.size - size;
}
