// 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.

// @dart = 2.9

import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:math';

import "vm_service_heap_helper.dart" as helper;

Completer completer;

Set<String> files = {};

// General idea: Do the once-a-week leak testing script
// => In this file:
//    * Start the frontend_server
//    * Do a compilation
//    * Pause the VM and do a "leak iteration"
//    * Once the VM has been unpaused, do an invalidation etc and repeat.
//
// This script also makes sure to clone flutter gallery,
// but assumes that flutter has been setup as by the script
// `tools/bots/flutter/compile_flutter.sh`.

main(List<String> args) async {
  if (Platform.isWindows) {
    throw "This script cannot run on Windows as it uses non-Windows "
        "assumptions both for the placement of pub packages and the presence "
        "of 'ln' for symbolic links. It has only been tested on Linux but will "
        "probably also work on Mac.";
  }

  bool quicker = false;
  bool alternativeInvalidation = false;
  String rootPath;

  for (String arg in args) {
    if (arg == "--quicker") {
      quicker = true;
    } else if (arg == "--alternativeInvalidation") {
      alternativeInvalidation = true;
    } else if (arg.startsWith("--path=")) {
      rootPath = arg.substring("--path=".length);
    } else {
      throw "Unknown argument '$arg'";
    }
  }

  if (rootPath == null) {
    throw "No path given. Pass with --path=<path>";
  }

  Directory patchedSdk = new Directory("$rootPath/flutter_patched_sdk/");
  if (!patchedSdk.existsSync()) {
    throw "Directory $patchedSdk doesn't exist.";
  }
  Uri frontendServerStarter = Platform.script
      .resolve("../../frontend_server/bin/frontend_server_starter.dart");
  if (!new File.fromUri(frontendServerStarter).existsSync()) {
    throw "File not found: $frontendServerStarter";
  }

  Directory gallery = new Directory("$rootPath/gallery");
  if (!gallery.existsSync()) {
    print("Gallery not found... Attempting to clone via git.");
    // git clone https://github.com/flutter/gallery.git
    Process process = await Process.start("git", [
      "clone",
      "https://github.com/flutter/gallery.git",
      "$rootPath/gallery"
    ]);
    process.stdout
        .transform(utf8.decoder)
        .transform(new LineSplitter())
        .listen((line) {
      print("git stdout> $line");
    });
    process.stderr
        .transform(utf8.decoder)
        .transform(new LineSplitter())
        .listen((line) {
      print("git stderr> $line");
    });
    int processExitCode = await process.exitCode;
    print("Exit code from git: $processExitCode");

    process = await Process.start("../flutter/bin/flutter", ["pub", "get"],
        workingDirectory: "$rootPath/gallery/");
    process.stdout
        .transform(utf8.decoder)
        .transform(new LineSplitter())
        .listen((line) {
      print("flutter stdout> $line");
    });
    process.stderr
        .transform(utf8.decoder)
        .transform(new LineSplitter())
        .listen((line) {
      print("flutter stderr> $line");
    });
    processExitCode = await process.exitCode;
    print("Exit code from flutter: $processExitCode");

    // Attempt to hack around strings being truncated to 128 bytes in heap dumps
    // https://github.com/dart-lang/sdk/blob/c59cdee365b94ce066344840f9e3412d642019b5/runtime/vm/object_graph.cc#L809
    // (pub paths can become too long, so two distinct files will look to have
    // the same url and thus give a false positive).
    Uri pubDirUri = Uri.parse("file://${Platform.environment['HOME']}/"
        ".pub-cache/hosted/pub.dartlang.org/");
    Directory pubDir = new Directory.fromUri(pubDirUri);
    if (!pubDir.existsSync()) throw "Expected to find $pubDir";
    File galleryDotPackages = new File("$rootPath/gallery/.packages");
    if (!galleryDotPackages.existsSync()) {
      throw "Didn't find $galleryDotPackages";
    }
    String data = galleryDotPackages.readAsStringSync();
    data = data.replaceAll(pubDirUri.toString(), "pub/");
    galleryDotPackages.writeAsStringSync(data);

    File galleryPackageConfig =
        new File("$rootPath/gallery/.dart_tool/package_config.json");
    if (!galleryPackageConfig.existsSync()) {
      throw "Didn't find $galleryPackageConfig";
    }
    data = galleryPackageConfig.readAsStringSync();
    data = data.replaceAll(pubDirUri.toString(), "../pub/");
    galleryPackageConfig.writeAsStringSync(data);

    process = await Process.start("ln", ["-s", pubDir.path, "pub"],
        workingDirectory: "$rootPath/gallery/");
    process.stdout
        .transform(utf8.decoder)
        .transform(new LineSplitter())
        .listen((line) {
      print("ln stdout> $line");
    });
    process.stderr
        .transform(utf8.decoder)
        .transform(new LineSplitter())
        .listen((line) {
      print("ln stderr> $line");
    });
    processExitCode = await process.exitCode;
    print("Exit code from ln: $processExitCode");
  }

  File galleryDotPackages = new File("$rootPath/gallery/.packages");
  if (!galleryDotPackages.existsSync()) {
    throw "Didn't find $galleryDotPackages";
  }

  List<helper.Interest> interests = <helper.Interest>[];
  interests.add(new helper.Interest(
    Uri.parse("package:kernel/ast.dart"),
    "Library",
    ["fileUri"],
  ));
  helper.VMServiceHeapHelperSpecificExactLeakFinder heapHelper =
      new helper.VMServiceHeapHelperSpecificExactLeakFinder(
    interests: interests,
    prettyPrints: [
      new helper.Interest(
        Uri.parse("package:kernel/ast.dart"),
        "Library",
        ["fileUri", "libraryIdForTesting"],
      ),
    ],
    throwOnPossibleLeak: true,
  );

  print("About to run with "
      "quicker = $quicker; "
      "alternativeInvalidation = $alternativeInvalidation; "
      "path = $rootPath; "
      "...");

  List<String> processArgs = [
    "--disable_dart_dev",
    "--disable-service-auth-codes",
    frontendServerStarter.toString(),
    "--sdk-root",
    "$rootPath/flutter_patched_sdk/",
    "--incremental",
    "--target=flutter",
    "--debugger-module-names",
    "--output-dill",
    "$rootPath/flutter_server_tmp.dill",
    "--packages",
    "$rootPath/gallery/.packages",
    "-Ddart.vm.profile=false",
    "-Ddart.vm.product=false",
    "--enable-asserts",
    "--track-widget-creation",
    "--initialize-from-dill",
    "$rootPath/cache.dill",
  ];
  if (alternativeInvalidation) {
    processArgs.add("--enable-experiment=alternative-invalidation-strategy");
  }

  await heapHelper.start(processArgs,
      stdoutReceiver: (s) {
        if (s.startsWith("+")) {
          files.add(s.substring(1));
        } else if (s.startsWith("-")) {
          files.remove(s.substring(1));
        } else {
          List<String> split = s.split(" ");
          if (int.tryParse(split.last) != null &&
              split[split.length - 2].endsWith(".dill")) {
            // e.g. something like "filename.dill 0" for output file and 0
            // errors.
            completer.complete();
          } else {
            print("out> $s");
          }
        }
      },
      stderrReceiver: (s) => print("err> $s"));

  Stopwatch stopwatch = new Stopwatch()..start();
  await sendAndWait(heapHelper.process, ['compile package:gallery/main.dart']);
  print("First compile took ${stopwatch.elapsedMilliseconds} ms");
  await pauseAndWait(heapHelper);

  await recompileAndWait(heapHelper.process, "package:gallery/main.dart", []);
  await accept(heapHelper);
  await sendAndWaitSetSelection(heapHelper.process);
  await sendAndWaitToObjectForSourceLocation(heapHelper.process);
  await sendAndWaitToObject(heapHelper.process);
  await pauseAndWait(heapHelper);

  print("Knows about ${files.length} files...");
  List<String> listFiles = new List<String>.from(files);
  int iteration = 0;
  for (String s in listFiles) {
    print("On iteration ${iteration++} / ${listFiles.length}");
    print(" => Invalidating $s");
    stopwatch.reset();
    await recompileAndWait(
        heapHelper.process, "package:gallery/main.dart", [s]);
    await accept(heapHelper);
    print("Recompile took ${stopwatch.elapsedMilliseconds} ms");
    await sendAndWaitSetSelection(heapHelper.process);
    await sendAndWaitToObjectForSourceLocation(heapHelper.process);
    await sendAndWaitToObject(heapHelper.process);
    if (quicker) {
      if (iteration % 10 == 0) {
        await pauseAndWait(heapHelper);
      }
    } else {
      await pauseAndWait(heapHelper);
    }
  }
  if (quicker) {
    await pauseAndWait(heapHelper);
  }

  // We should now be done.
  print("Done!");
  heapHelper.process.kill();
}

Future accept(
    helper.VMServiceHeapHelperSpecificExactLeakFinder heapHelper) async {
  heapHelper.process.stdin.writeln('accept');
  int waits = 0;
  while (!await heapHelper.isIdle()) {
    if (waits > 100) {
      // Waited for at least 10 seconds --- assume there's something wrong.
      throw "Timed out waiting to become idle!";
    }
    await new Future.delayed(new Duration(milliseconds: 100));
    waits++;
  }
}

class Uuid {
  final Random _random = new Random();

  /// Generate a version 4 (random) uuid. This is a uuid scheme that only uses
  /// random numbers as the source of the generated uuid.
  String generateV4() {
    // Generate xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx / 8-4-4-4-12.
    int special = 8 + _random.nextInt(4);

    return '${_bitsDigits(16, 4)}${_bitsDigits(16, 4)}-'
        '${_bitsDigits(16, 4)}-'
        '4${_bitsDigits(12, 3)}-'
        '${_printDigits(special, 1)}${_bitsDigits(12, 3)}-'
        '${_bitsDigits(16, 4)}${_bitsDigits(16, 4)}${_bitsDigits(16, 4)}';
  }

  String _bitsDigits(int bitCount, int digitCount) =>
      _printDigits(_generateBits(bitCount), digitCount);

  int _generateBits(int bitCount) => _random.nextInt(1 << bitCount);

  String _printDigits(int value, int count) =>
      value.toRadixString(16).padLeft(count, '0');
}

Future pauseAndWait(
    helper.VMServiceHeapHelperSpecificExactLeakFinder heapHelper) async {
  int prevIterationNumber = heapHelper.iterationNumber;
  await heapHelper.pause();

  int waits = 0;
  while (heapHelper.iterationNumber == prevIterationNumber) {
    if (waits > 10000) {
      // Waited for at least 1000 seconds --- assume there's something wrong.
      throw "Timed out waiting for the helper iteration number to increase!";
    }
    await new Future.delayed(new Duration(milliseconds: 100));
    waits++;
  }
}

Future recompileAndWait(
    Process _server, String what, List<String> invalidates) async {
  String inputKey = Uuid().generateV4();
  List<String> data = ['recompile $what $inputKey'];
  invalidates.forEach(data.add);
  data.add('$inputKey');
  await sendAndWait(_server, data);
}

Future sendAndWait(Process _server, List<String> data) async {
  completer = new Completer();
  data.forEach(_server.stdin.writeln);
  await completer.future;
}

Future sendAndWaitDebugDidSendFirstFrameEvent(Process _server) async {
  String inputKey = Uuid().generateV4();
  await sendAndWait(_server, [
    /* 'compile-expression' <boundarykey> */ 'compile-expression $inputKey',
    /* expression */ 'WidgetsBinding.instance.debugDidSendFirstFrameEvent',
    /* no definitions */
    /* <boundarykey> */ inputKey,
    /* no type-defintions */
    /* <boundarykey> */ inputKey,
    /* libraryUri */ 'package:flutter/src/widgets/binding.dart',
    /* class */ '',
    /* isStatic */ 'true'
  ]);
}

Future sendAndWaitSetSelection(Process _server) async {
  String inputKey = Uuid().generateV4();
  await sendAndWait(_server, [
    /* 'compile-expression' <boundarykey> */ 'compile-expression $inputKey',
    /* expression */ 'WidgetInspectorService.instance.setSelection('
        'arg1, "dummy_68")',
    /* definition #1 */ 'arg1',
    /* <boundarykey> */ inputKey,
    /* no type-defintions */
    /* <boundarykey> */ inputKey,
    /* libraryUri */ 'package:flutter/src/widgets/widget_inspector.dart',
    /* class */ '',
    /* isStatic */ 'true'
  ]);
}

Future sendAndWaitToObject(Process _server) async {
  String inputKey = Uuid().generateV4();
  await sendAndWait(_server, [
    /* 'compile-expression' <boundarykey> */ 'compile-expression $inputKey',
    /* expression */ 'WidgetInspectorService.instance.toObject('
        '"inspector-836", "tree_112")',
    /* no definitions */
    /* <boundarykey> */ inputKey,
    /* no type-defintions */
    /* <boundarykey> */ inputKey,
    /* libraryUri */ 'package:flutter/src/widgets/widget_inspector.dart',
    /* class */ '',
    /* isStatic */ 'true'
  ]);
}

Future sendAndWaitToObjectForSourceLocation(Process _server) async {
  String inputKey = Uuid().generateV4();
  await sendAndWait(_server, [
    /* 'compile-expression' <boundarykey> */ 'compile-expression $inputKey',
    /* expression */ 'WidgetInspectorService.instance.'
        'toObjectForSourceLocation("inspector-607", "tree_112")',
    /* no definitions */
    /* <boundarykey> */ inputKey,
    /* no type-defintions */
    /* <boundarykey> */ inputKey,
    /* libraryUri */ 'package:flutter/src/widgets/widget_inspector.dart',
    /* class */ '',
    /* isStatic */ 'true'
  ]);
}
