// Copyright 2014 The Flutter Authors. 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.8

import 'dart:async';

import 'package:file/memory.dart';
import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/async_guard.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/compile.dart';
import 'package:flutter_tools/src/convert.dart';
import 'package:package_config/package_config.dart';

import '../src/common.dart';
import '../src/fake_process_manager.dart';
import '../src/fakes.dart';

void main() {
  ResidentCompiler generator;
  ResidentCompiler generatorWithScheme;
  MemoryIOSink frontendServerStdIn;
  BufferLogger testLogger;
  StdoutHandler generatorStdoutHandler;
  StdoutHandler generatorWithSchemeStdoutHandler;
  FakeProcessManager fakeProcessManager;

  const List<String> frontendServerCommand = <String>[
    'Artifact.engineDartBinary',
    '--disable-dart-dev',
    'Artifact.frontendServerSnapshotForEngineDartSdk',
    '--sdk-root',
    'sdkroot/',
    '--incremental',
    '--target=flutter',
    '--debugger-module-names',
    '--experimental-emit-debug-metadata',
    '--output-dill',
    '/build/',
    '-Ddart.vm.profile=false',
    '-Ddart.vm.product=false',
    '--enable-asserts',
    '--track-widget-creation',
  ];

  setUp(() {
    testLogger = BufferLogger.test();
    frontendServerStdIn = MemoryIOSink();

    fakeProcessManager = FakeProcessManager.list(<FakeCommand>[]);
    generatorStdoutHandler = StdoutHandler(logger: testLogger, fileSystem: MemoryFileSystem.test());
    generatorWithSchemeStdoutHandler = StdoutHandler(logger: testLogger, fileSystem: MemoryFileSystem.test());
    generator = DefaultResidentCompiler(
      'sdkroot',
      buildMode: BuildMode.debug,
      logger: testLogger,
      processManager: fakeProcessManager,
      artifacts: Artifacts.test(),
      platform: FakePlatform(operatingSystem: 'linux'),
      fileSystem: MemoryFileSystem.test(),
      stdoutHandler: generatorStdoutHandler,
    );
    generatorWithScheme = DefaultResidentCompiler(
      'sdkroot',
      buildMode: BuildMode.debug,
      logger: testLogger,
      processManager: fakeProcessManager,
      artifacts: Artifacts.test(),
      platform: FakePlatform(operatingSystem: 'linux'),
      fileSystemRoots: <String>[
        '/foo/bar/fizz',
      ],
      fileSystemScheme: 'scheme',
      fileSystem: MemoryFileSystem.test(),
      stdoutHandler: generatorWithSchemeStdoutHandler,
    );
  });

  testWithoutContext('incremental compile single dart compile', () async {
    fakeProcessManager.addCommand(FakeCommand(
      command: frontendServerCommand,
      stdout: 'result abc\nline1\nline2\nabc\nabc /path/to/main.dart.dill 0',
      stdin: frontendServerStdIn,
    ));

    final CompilerOutput output = await generator.recompile(
      Uri.parse('/path/to/main.dart'),
        null /* invalidatedFiles */,
      outputPath: '/build/',
      packageConfig: PackageConfig.empty,
    );
    expect(frontendServerStdIn.getAndClear(), 'compile /path/to/main.dart\n');
    expect(testLogger.errorText, equals('line1\nline2\n'));
    expect(output.outputFilename, equals('/path/to/main.dart.dill'));
    expect(fakeProcessManager, hasNoRemainingExpectations);
  });

  testWithoutContext('incremental compile single dart compile with filesystem scheme', () async {
    fakeProcessManager.addCommand(FakeCommand(
      command: const <String>[
        ...frontendServerCommand,
        '--filesystem-root',
        '/foo/bar/fizz',
        '--filesystem-scheme',
        'scheme',
      ],
      stdout: 'result abc\nline1\nline2\nabc\nabc /path/to/main.dart.dill 0',
      stdin: frontendServerStdIn,
    ));

    final CompilerOutput output = await generatorWithScheme.recompile(
      Uri.parse('file:///foo/bar/fizz/main.dart'),
        null /* invalidatedFiles */,
      outputPath: '/build/',
      packageConfig: PackageConfig.empty,
    );
    expect(frontendServerStdIn.getAndClear(), 'compile scheme:///main.dart\n');
    expect(testLogger.errorText, equals('line1\nline2\n'));
    expect(output.outputFilename, equals('/path/to/main.dart.dill'));
    expect(fakeProcessManager, hasNoRemainingExpectations);
  });

  testWithoutContext('incremental compile single dart compile abnormally terminates', () async {
    fakeProcessManager.addCommand(FakeCommand(
      command: frontendServerCommand,
      stdin: frontendServerStdIn,
    ));

    expect(asyncGuard(() => generator.recompile(
      Uri.parse('/path/to/main.dart'),
      null, /* invalidatedFiles */
      outputPath: '/build/',
      packageConfig: PackageConfig.empty,
    )), throwsToolExit());
  });

  testWithoutContext('incremental compile single dart compile abnormally terminates via exitCode', () async {
    fakeProcessManager.addCommand(FakeCommand(
      command: frontendServerCommand,
      stdin: frontendServerStdIn,
      exitCode: 1,
    ));

    expect(asyncGuard(() => generator.recompile(
      Uri.parse('/path/to/main.dart'),
      null, /* invalidatedFiles */
      outputPath: '/build/',
      packageConfig: PackageConfig.empty,
    )), throwsToolExit(message: 'the Dart compiler exited unexpectedly.'));
  });

  testWithoutContext('incremental compile and recompile', () async {
    final Completer<void> completer = Completer<void>();
    fakeProcessManager.addCommand(FakeCommand(
      command: frontendServerCommand,
      stdout: 'result abc\nline0\nline1\nabc\nabc /path/to/main.dart.dill 0',
      stdin: frontendServerStdIn,
      completer: completer,
    ));

    await generator.recompile(
      Uri.parse('/path/to/main.dart'),
      null, /* invalidatedFiles */
      outputPath: '/build/',
      packageConfig: PackageConfig.empty,
    );
    expect(frontendServerStdIn.getAndClear(), 'compile /path/to/main.dart\n');

    // No accept or reject commands should be issued until we
    // send recompile request.
    await _accept(generator, frontendServerStdIn, '');
    await _reject(generatorStdoutHandler, generator, frontendServerStdIn, '', '');

    await _recompile(generatorStdoutHandler, generator, frontendServerStdIn,
      'result abc\nline1\nline2\nabc\nabc /path/to/main.dart.dill 0\n');

    await _accept(generator, frontendServerStdIn, r'^accept\n$');

    await _recompile(generatorStdoutHandler, generator, frontendServerStdIn,
      'result abc\nline1\nline2\nabc\nabc /path/to/main.dart.dill 0\n');
    // No sources returned from reject command.
    await _reject(generatorStdoutHandler, generator, frontendServerStdIn, 'result abc\nabc\n',
      r'^reject\n$');
    completer.complete();
    expect(frontendServerStdIn.getAndClear(), isEmpty);
    expect(testLogger.errorText, equals(
      'line0\nline1\n'
      'line1\nline2\n'
      'line1\nline2\n'
    ));
  });

  testWithoutContext('incremental compile and recompile with filesystem scheme', () async {
    final Completer<void> completer = Completer<void>();
    fakeProcessManager.addCommand(FakeCommand(
      command: const <String>[
        ...frontendServerCommand,
        '--filesystem-root',
        '/foo/bar/fizz',
        '--filesystem-scheme',
        'scheme',
      ],
      stdout: 'result abc\nline0\nline1\nabc\nabc /path/to/main.dart.dill 0',
      stdin: frontendServerStdIn,
      completer: completer,
    ));
    await generatorWithScheme.recompile(
      Uri.parse('file:///foo/bar/fizz/main.dart'),
      null, /* invalidatedFiles */
      outputPath: '/build/',
      packageConfig: PackageConfig.empty,
    );
    expect(frontendServerStdIn.getAndClear(), 'compile scheme:///main.dart\n');

    // No accept or reject commands should be issued until we
    // send recompile request.
    await _accept(generatorWithScheme, frontendServerStdIn, '');
    await _reject(generatorWithSchemeStdoutHandler, generatorWithScheme, frontendServerStdIn, '', '');

    await _recompile(generatorWithSchemeStdoutHandler, generatorWithScheme, frontendServerStdIn,
      'result abc\nline1\nline2\nabc\nabc /path/to/main.dart.dill 0\n',
      mainUri: Uri.parse('file:///foo/bar/fizz/main.dart'),
      expectedMainUri: 'scheme:///main.dart');

    await _accept(generatorWithScheme, frontendServerStdIn, r'^accept\n$');

    await _recompile(generatorWithSchemeStdoutHandler, generatorWithScheme, frontendServerStdIn,
      'result abc\nline1\nline2\nabc\nabc /path/to/main.dart.dill 0\n',
      mainUri: Uri.parse('file:///foo/bar/fizz/main.dart'),
      expectedMainUri: 'scheme:///main.dart');
    // No sources returned from reject command.
    await _reject(generatorWithSchemeStdoutHandler, generatorWithScheme, frontendServerStdIn, 'result abc\nabc\n',
      r'^reject\n$');
    completer.complete();
    expect(frontendServerStdIn.getAndClear(), isEmpty);
    expect(testLogger.errorText, equals(
      'line0\nline1\n'
      'line1\nline2\n'
      'line1\nline2\n'
    ));
  });

  testWithoutContext('incremental compile and recompile non-entrypoint file with filesystem scheme', () async {
    final Uri mainUri = Uri.parse('file:///foo/bar/fizz/main.dart');
    const String expectedMainUri = 'scheme:///main.dart';
    final List<Uri> updatedUris = <Uri>[
      mainUri,
      Uri.parse('file:///foo/bar/fizz/other.dart'),
    ];
    const List<String> expectedUpdatedUris = <String>[
      expectedMainUri,
      'scheme:///other.dart',
    ];

    final Completer<void> completer = Completer<void>();
    fakeProcessManager.addCommand(FakeCommand(
      command: const <String>[
        ...frontendServerCommand,
        '--filesystem-root',
        '/foo/bar/fizz',
        '--filesystem-scheme',
        'scheme',
      ],
      stdout: 'result abc\nline0\nline1\nabc\nabc /path/to/main.dart.dill 0',
      stdin: frontendServerStdIn,
      completer: completer,
    ));
    await generatorWithScheme.recompile(
      Uri.parse('file:///foo/bar/fizz/main.dart'),
      null, /* invalidatedFiles */
      outputPath: '/build/',
      packageConfig: PackageConfig.empty,
    );
    expect(frontendServerStdIn.getAndClear(), 'compile scheme:///main.dart\n');

    // No accept or reject commands should be issued until we
    // send recompile request.
    await _accept(generatorWithScheme, frontendServerStdIn, '');
    await _reject(generatorWithSchemeStdoutHandler, generatorWithScheme, frontendServerStdIn, '', '');

    await _recompile(generatorWithSchemeStdoutHandler, generatorWithScheme, frontendServerStdIn,
      'result abc\nline1\nline2\nabc\nabc /path/to/main.dart.dill 0\n',
      mainUri: mainUri,
      expectedMainUri: expectedMainUri,
      updatedUris: updatedUris,
      expectedUpdatedUris: expectedUpdatedUris);

    await _accept(generatorWithScheme, frontendServerStdIn, r'^accept\n$');

    await _recompile(generatorWithSchemeStdoutHandler, generatorWithScheme, frontendServerStdIn,
      'result abc\nline1\nline2\nabc\nabc /path/to/main.dart.dill 0\n',
      mainUri: mainUri,
      expectedMainUri: expectedMainUri,
      updatedUris: updatedUris,
      expectedUpdatedUris: expectedUpdatedUris);
    // No sources returned from reject command.
    await _reject(generatorWithSchemeStdoutHandler, generatorWithScheme, frontendServerStdIn, 'result abc\nabc\n',
      r'^reject\n$');
    completer.complete();
    expect(frontendServerStdIn.getAndClear(), isEmpty);
    expect(testLogger.errorText, equals(
      'line0\nline1\n'
      'line1\nline2\n'
      'line1\nline2\n'
    ));
  });

  testWithoutContext('incremental compile can suppress errors', () async {
    final Completer<void> completer = Completer<void>();
    fakeProcessManager.addCommand(FakeCommand(
      command: frontendServerCommand,
      stdout: 'result abc\nline0\nline1\nabc\nabc /path/to/main.dart.dill 0',
      stdin: frontendServerStdIn,
      completer: completer,
    ));

    await generator.recompile(
      Uri.parse('/path/to/main.dart'),
      <Uri>[],
      outputPath: '/build/',
      packageConfig: PackageConfig.empty,
    );
    expect(frontendServerStdIn.getAndClear(), 'compile /path/to/main.dart\n');

    await _recompile(generatorStdoutHandler, generator, frontendServerStdIn,
      'result abc\nline1\nline2\nabc\nabc /path/to/main.dart.dill 0\n');

    await _accept(generator, frontendServerStdIn, r'^accept\n$');

    await _recompile(generatorStdoutHandler, generator, frontendServerStdIn,
      'result abc\nline1\nline2\nabc\nabc /path/to/main.dart.dill 0\n', suppressErrors: true);

    completer.complete();
    expect(frontendServerStdIn.getAndClear(), isEmpty);

    // Compiler message is not printed with suppressErrors: true above.
    expect(testLogger.errorText, isNot(equals(
      'line1\nline2\n'
    )));
    expect(testLogger.traceText, contains(
      'line1\nline2\n'
    ));
  });

  testWithoutContext('incremental compile and recompile twice', () async {
    final Completer<void> completer = Completer<void>();
    fakeProcessManager.addCommand(FakeCommand(
      command: frontendServerCommand,
      stdout: 'result abc\nline0\nline1\nabc\nabc /path/to/main.dart.dill 0',
      stdin: frontendServerStdIn,
      completer: completer,
    ));
    await generator.recompile(
      Uri.parse('/path/to/main.dart'),
      null /* invalidatedFiles */,
      outputPath: '/build/',
      packageConfig: PackageConfig.empty,
    );
    expect(frontendServerStdIn.getAndClear(), 'compile /path/to/main.dart\n');

    await _recompile(generatorStdoutHandler, generator, frontendServerStdIn,
      'result abc\nline1\nline2\nabc\nabc /path/to/main.dart.dill 0\n');
    await _recompile(generatorStdoutHandler, generator, frontendServerStdIn,
      'result abc\nline2\nline3\nabc\nabc /path/to/main.dart.dill 0\n');

    completer.complete();
    expect(frontendServerStdIn.getAndClear(), isEmpty);
    expect(testLogger.errorText, equals(
      'line0\nline1\n'
      'line1\nline2\n'
      'line2\nline3\n'
    ));
  });
}

Future<void> _recompile(
  StdoutHandler stdoutHandler,
  ResidentCompiler generator,
  MemoryIOSink frontendServerStdIn,
  String mockCompilerOutput, {
  bool suppressErrors = false,
  Uri mainUri,
  String expectedMainUri = '/path/to/main.dart',
  List<Uri> updatedUris,
  List<String> expectedUpdatedUris,
}) async {
  mainUri ??= Uri.parse('/path/to/main.dart');
  updatedUris ??= <Uri>[mainUri];
  expectedUpdatedUris ??= <String>[expectedMainUri];

  final Future<CompilerOutput> recompileFuture = generator.recompile(
    mainUri,
    updatedUris,
    outputPath: '/build/',
    packageConfig: PackageConfig.empty,
    suppressErrors: suppressErrors,
  );

  // Put content into the output stream after generator.recompile gets
  // going few lines below, resets completer.
  scheduleMicrotask(() {
    LineSplitter.split(mockCompilerOutput).forEach(stdoutHandler.handler);
  });
  final CompilerOutput output = await recompileFuture;
  expect(output.outputFilename, equals('/path/to/main.dart.dill'));
  final String commands = frontendServerStdIn.getAndClear();
  final RegExp whitespace = RegExp(r'\s+');
  final List<String> parts = commands.split(whitespace);

  // Test that uuid matches at beginning and end.
  expect(parts[2], equals(parts[3 + updatedUris.length]));
  expect(parts[1], equals(expectedMainUri));
  for (int i = 0; i < expectedUpdatedUris.length; i++) {
    expect(parts[3 + i], equals(expectedUpdatedUris[i]));
  }
}

Future<void> _accept(
  ResidentCompiler generator,
  MemoryIOSink frontendServerStdIn,
  String expected,
) async {
  generator.accept();
  final String commands = frontendServerStdIn.getAndClear();
  final RegExp re = RegExp(expected);
  expect(commands, matches(re));
}

Future<void> _reject(
  StdoutHandler stdoutHandler,
  ResidentCompiler generator,
  MemoryIOSink frontendServerStdIn,
  String mockCompilerOutput,
  String expected,
) async {
  // Put content into the output stream after generator.recompile gets
  // going few lines below, resets completer.
  final Future<CompilerOutput> rejectFuture = generator.reject();
  scheduleMicrotask(() {
    LineSplitter.split(mockCompilerOutput).forEach(stdoutHandler.handler);
  });
  final CompilerOutput output = await rejectFuture;
  expect(output, isNull);

  final String commands = frontendServerStdIn.getAndClear();
  final RegExp re = RegExp(expected);
  expect(commands, matches(re));
}
