// Copyright 2020 The Fuchsia Authors. 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:async';
import 'dart:convert';
import 'dart:io';

import 'package:blobstats/blob.dart';
import 'package:blobstats/dart_package.dart';
import 'package:blobstats/package.dart';
import 'package:path/path.dart' as p;

class BlobStats {
  Directory buildDir;
  Directory outputDir;
  String suffix;
  bool humanReadable;
  Map<String, Blob> blobsByHash = <String, Blob>{};
  int duplicatedSize = 0;
  int deduplicatedSize = 0;
  List<File> pendingPackages = <File>[];
  List<Package> packages = <Package>[];

  BlobStats(this.buildDir, this.outputDir, this.suffix,
      {this.humanReadable = false});

  Future addManifest(String dir, String name) async {
    var lines = await File(p.join(buildDir.path, dir, name)).readAsLines();
    for (var line in lines) {
      var parts = line.split('=');
      var hash = parts[0];
      // Path entries are specified relative to the directory containing the manifest.
      var entryPath = p.join(dir, parts[1]);
      var file = File(entryPath);
      if (entryPath.endsWith('meta.far')) {
        pendingPackages.add(file);
      }

      if (suffix != null && !entryPath.endsWith(suffix)) {
        continue;
      }

      var stat = file.statSync();
      if (stat.type == FileSystemEntityType.notFound) {
        print('$entryPath does not exist [Make sure the build is up to date]');
        continue;
      }
      var blob = blobsByHash[hash];
      if (blob == null) {
        var blob = Blob()
          ..hash = hash
          ..buildPath = entryPath
          ..sizeOnHost = stat.size
          ..count = 0;
        blobsByHash[hash] = blob;
      }
    }
  }

  Future addBlobSizes(String path) async {
    var blobs =
        json.decode(await File(p.join(buildDir.path, path)).readAsString());
    for (var blob in blobs) {
      var b = blobsByHash[blob['merkle']];
      if (b != null) {
        b.size = blob['size'];
      }
    }
  }

  void printBlobList(List<Blob> blobs, int limit) {
    print('     Size Share      Prop     Saved Path');
    var n = 0;
    for (var blob in blobs) {
      if (n++ > limit) return;

      var sb = StringBuffer()
        ..write(formatSize(blob.size).padLeft(9))
        ..write(' ')
        ..write(blob.count.toString().padLeft(5))
        ..write(' ')
        ..write(formatSize(blob.proportional).padLeft(9))
        ..write(' ')
        ..write(formatSize(blob.saved).padLeft(9))
        ..write(' ')
        ..write(blob.sourcePath);
      print(sb);
    }
  }

  void printBlobs(int limit) {
    var blobs = blobsByHash.values.toList();
    print('Top blobs by size ($limit of ${blobs.length})');
    blobs.sort((a, b) => b.size.compareTo(a.size));
    printBlobList(blobs, limit);

    blobs.removeWhere((blob) => blob.count == 1);

    print('');
    print('Top deduplicated blobs by proportional ($limit of ${blobs.length})');
    blobs.sort((a, b) => b.proportional.compareTo(a.proportional));
    printBlobList(blobs, limit);

    print('');
    print('Top deduplicated blobs by saved ($limit of ${blobs.length})');
    blobs.sort((a, b) => b.saved.compareTo(a.saved));
    printBlobList(blobs, limit);
  }

  void printOverallSavings() {
    var percent = (duplicatedSize - deduplicatedSize) * 100 ~/ duplicatedSize;
    print('');
    print('Total savings from deduplication:');
    print(
        '   $percent% ${formatSize(deduplicatedSize)} / ${formatSize(duplicatedSize)}');
  }

  String metaFarToBlobsJson(String farPath) {
    // Assumes details of //build/package.gni, namely that it generates
    //   <build-dir>/.../<package>/meta.far
    // and puts a blobs.json file into
    //   <build-dir>/.../<package>/blobs.json
    if (!farPath.endsWith('/meta.far')) {
      throw ArgumentError('Build details have changed');
    }
    String path = '${removeSuffix(farPath, 'meta.far')}blobs.json';
    if (!File(path).existsSync()) {
      throw ArgumentError(
          'Build details have changed - path to blobs.json $path not found for $farPath');
    }
    return path;
  }

  Future computePackagesInParallel(int jobs) async {
    var tasks = <Future>[];
    for (var i = 0; i < jobs; i++) {
      tasks.add(computePackages());
    }
    await Future.wait(tasks);
  }

  Future computePackages() async {
    while (pendingPackages.isNotEmpty) {
      File far = pendingPackages.removeLast();

      var package = Package()..path = far.path;
      var parts = package.path.split('/');
      package
        ..name = removeSuffix(
            parts.length > 1 ? parts[parts.length - 2] : parts.last, '.meta')
        ..size = 0
        ..proportional = 0
        ..private = 0
        ..blobCount = 0
        ..blobsByPath = <String, Blob>{};

      var blobs =
          json.decode(await File(metaFarToBlobsJson(far.path)).readAsString());

      for (var blob in blobs) {
        var hash = blob['merkle'];
        var path = blob['path'];
        var b = blobsByHash[hash];
        if (b == null) {
          print(
              '$path $hash is in a package manifest but not the final manifest');
          continue;
        }
        b.count++;
        var sourcePath = blob['source_path'];
        // If the source_path looks like <something>/blobs/<merkle>, it from a prebuilt package and has no
        // meaningful source. Instead, use the path within the package as its identifier.
        if (sourcePath.endsWith('/blobs/$hash')) {
          sourcePath = path;
        }
        // We may see the same blob referenced from different packages with different source paths.
        // If all references agree with each other, use that.
        // Otherwise record the first observed path and append ' *' to denote that the path is only one of many.
        if (b.sourcePath == 'Unknown') {
          b.sourcePath = sourcePath;
        } else if (b.sourcePath != sourcePath && !b.sourcePath.endsWith(' *')) {
          b.sourcePath = '${b.sourcePath} *';
        }
        package.blobsByPath[path] = b;
      }

      packages.add(package);
    }
  }

  void computeStats() {
    var filteredBlobs = <String, Blob>{};
    blobsByHash.forEach((hash, blob) {
      if (blob.count == 0) {
        print(
            '${blob.hash} is in the final manifest but not any package manifest');
      } else {
        filteredBlobs[hash] = blob;
      }
    });
    blobsByHash = filteredBlobs;

    for (var blob in blobsByHash.values) {
      duplicatedSize += (blob.size * blob.count);
      deduplicatedSize += blob.size;
    }

    for (var package in packages) {
      for (var blob in package.blobsByPath.values) {
        package
          ..size += blob.size
          ..proportional += blob.proportional;
        if (blob.count == 1) {
          package.private += blob.size;
        }
        package.blobCount++;
      }
    }
  }

  void printPackages() {
    packages.sort((a, b) => b.proportional.compareTo(a.proportional));
    print('');
    print('Packages by proportional (${packages.length})');
    print('     Size      Prop   Private Name');
    for (var package in packages) {
      var sb = StringBuffer()
        ..write(formatSize(package.size).padLeft(9))
        ..write(' ')
        ..write(formatSize(package.proportional).padLeft(9))
        ..write(' ')
        ..write(formatSize(package.private).padLeft(9))
        ..write(' ')
        ..write(package.name);
      print(sb);
    }
  }

  Future packagesToChromiumBinarySizeTree() async {
    var rootTree = {};
    rootTree['n'] = 'packages';
    rootTree['children'] = [];
    rootTree['k'] = 'p'; // kind=path
    for (var pkg in packages) {
      var pkgTree = {};
      pkgTree['n'] = pkg.name;
      pkgTree['children'] = [];
      pkgTree['k'] = 'p'; // kind=path
      rootTree['children'].add(pkgTree);
      pkg.blobsByPath.forEach((path, blob) {
        var blobName = path; //path.split('/').last;
        var blobTree = {};
        blobTree['n'] = blobName;
        blobTree['k'] = 's'; // kind=blob
        var isUnique = blob.count == 1;
        var isDart =
            blobName.endsWith('.dilp') || blobName.endsWith('.aotsnapshot');
        if (isDart) {
          if (isUnique) {
            blobTree['t'] = 'uniDart';
          } else {
            blobTree['t'] = 'dart'; // type=Shared Dart ('blue')
          }
        } else {
          if (isUnique) {
            blobTree['t'] = 'unique';
          } else {
            blobTree['t'] = '?'; // type=Other ('red')
          }
        }
        blobTree['c'] = blob.count;
        blobTree['value'] = blob.proportional;
        blobTree['originalSize'] = blob.sizeOnHost;
        pkgTree['children'].add(blobTree);
      });
    }

    var sink = File(p.join(outputDir.path, 'data.js')).openWrite()
      ..write('var tree_data=')
      ..write(json.encode(rootTree));
    await sink.close();

    await Directory(p.join(outputDir.path, 'd3_v3')).create(recursive: true);
    var d3Dir = p.join(buildDir.path, '../../scripts/third_party/d3_v3/');
    for (var file in ['LICENSE', 'd3.js']) {
      await File(d3Dir + file).copy(p.join(outputDir.path, 'd3_v3', file));
    }
    var templateDir = p.join(buildDir.path, '../../tools/blobstats/template/');
    for (var file in ['index.html', 'D3BlobTreeMap.js']) {
      await File(templateDir + file).copy(p.join(outputDir.path, file));
    }

    print('Wrote visualization to ${p.join(outputDir.path, 'index.html')}');
  }

  void printDartPackages() async {
    var dartPackagesMap = <String, DartPackage>{};
    for (var fuchsiaPackage in packages) {
      fuchsiaPackage.blobsByPath.forEach((path, blob) {
        if (!path.endsWith('.dilp')) return;

        var dartPackageName = removeSuffix(path.split('/').last, '.dilp');
        if (dartPackageName == 'main') return;

        var dartPackage = dartPackagesMap.putIfAbsent(
            dartPackageName, () => DartPackage(dartPackageName));

        dartPackage.blobs.putIfAbsent(blob, () => []).add(fuchsiaPackage.name);
      });
    }

    var dartPackagesList = dartPackagesMap.values.toList()
      ..sort((a, b) => a.name.compareTo(b.name))
      ..sort((a, b) => a.blobs.length.compareTo(b.blobs.length));

    print('');
    print('Dart packages:');
    for (var dartPackage in dartPackagesList) {
      print('package:${dartPackage.name} (${dartPackage.blobs.length} blobs)');
      if (dartPackage.blobs.length == 1) {
        continue;
      }

      for (var blob in dartPackage.blobs.keys) {
        var fuchsiaPackages = dartPackage.blobs[blob];

        var result = await Process.run(Platform.executable, [
          '../../prebuilt/third_party/flutter/x64/debug/jit/dart_binaries/list_libraries.snapshot',
          blob.buildPath
        ]);
        if (result.exitCode != 0) {
          print(result.stdout);
          print(result.stderr);
          throw Exception('Failed to list libraries in kernel file');
        }
        var libraries = result.stdout.split('\n');
        libraries.remove('');

        print('  ${blob.hash} ${blob.buildPath}');
        print('    ${fuchsiaPackages.join(' ')}');
        for (var library in libraries) {
          print('    $library');
        }
      }
      print('');
    }
  }

  Future<String> csvBlobs() async {
    var path = p.join(outputDir.path, 'blobs.csv');
    var csv = File(path).openWrite()..writeln('Size,Share,Prop,Saved,Path');

    var blobs = blobsByHash.values.toList()
      ..sort((a, b) => b.size.compareTo(a.size));

    for (var blob in blobs) {
      var values = [
        blob.size,
        blob.count,
        blob.proportional,
        blob.saved,
        blob.sourcePath
      ];
      csv.writeln(values.join(','));
    }
    await csv.close();
    return path;
  }

  Future<String> csvPackages() async {
    var path = p.join(outputDir.path, 'packages.csv');
    var csv = File(path).openWrite()..writeln('Size,Prop,Private,Name');

    packages.sort((a, b) => b.proportional.compareTo(a.proportional));

    for (var package in packages) {
      var values = [
        package.size,
        package.proportional,
        package.private,
        package.name
      ];
      csv.writeln(values.join(','));
    }
    await csv.close();
    return path;
  }

  String formatSize(num size) {
    if (!humanReadable) return '$size';

    var formattedSize = size;
    if (formattedSize < 1024) return '$formattedSize';
    formattedSize /= 1024;
    if (formattedSize < 1024) return '${formattedSize.toStringAsFixed(1)}K';
    formattedSize /= 1024.0;
    if (formattedSize < 1024) return '${formattedSize.toStringAsFixed(1)}M';
    formattedSize /= 1024;
    return '${formattedSize.toStringAsFixed(1)}G';
  }

  String removeSuffix(String s, String suffix) {
    if (s.endsWith(suffix)) {
      return s.substring(0, s.length - suffix.length);
    }
    return s;
  }
}
