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

import 'package:file_testing/file_testing.dart';
import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/base/template.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/build_system/build_system.dart';
import 'package:flutter_tools/src/build_system/depfile.dart';
import 'package:flutter_tools/src/build_system/targets/web.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:flutter_tools/src/isolated/mustache_template.dart';
import 'package:flutter_tools/src/web/compile.dart';
import 'package:flutter_tools/src/web/file_generators/flutter_service_worker_js.dart';
import 'package:flutter_tools/src/web_template.dart';

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

const List<String> _kDart2jsLinuxArgs = <String>[
  'Artifact.engineDartBinary.TargetPlatform.web_javascript',
  '--disable-dart-dev',
  'Artifact.dart2jsSnapshot.TargetPlatform.web_javascript',
  '--platform-binaries=HostArtifact.webPlatformKernelFolder',
  '--invoker=flutter_tool',
];

const List<String> _kDart2WasmLinuxArgs = <String> [
  'Artifact.engineDartBinary.TargetPlatform.web_javascript',
  'compile',
  'wasm',
  '--packages=.dart_tool/package_config.json',
  '--extra-compiler-option=--dart-sdk=Artifact.engineDartSdkPath.TargetPlatform.web_javascript',
  '--extra-compiler-option=--platform=HostArtifact.webPlatformKernelFolder/dart2wasm_platform.dill',
  '--extra-compiler-option=--delete-tostring-package-uri=dart:ui',
  '--extra-compiler-option=--delete-tostring-package-uri=package:flutter',
];

void main() {
  late Testbed testbed;
  late Environment environment;
  late FakeProcessManager processManager;
  final Platform linux = FakePlatform(
    environment: <String, String>{},
  );
  final Platform windows = FakePlatform(
    operatingSystem: 'windows',
    environment: <String, String>{},
  );

  setUp(() {
    testbed = Testbed(setup: () {
      globals.fs.file('.packages')
        ..createSync(recursive: true)
        ..writeAsStringSync('foo:foo/lib/\n');
      globals.fs.currentDirectory.childDirectory('bar').createSync();
      processManager = FakeProcessManager.empty();
      globals.fs.file('bin/cache/flutter_web_sdk/flutter_js/flutter.js')
        .createSync(recursive: true);

      environment = Environment.test(
        globals.fs.currentDirectory,
        projectDir: globals.fs.currentDirectory.childDirectory('foo'),
        outputDir: globals.fs.currentDirectory.childDirectory('bar'),
        defines: <String, String>{
          kTargetFile: globals.fs.path.join('foo', 'lib', 'main.dart'),
        },
        artifacts: Artifacts.test(),
        processManager: processManager,
        logger: globals.logger,
        fileSystem: globals.fs,
      );
      environment.buildDir.createSync(recursive: true);
    }, overrides: <Type, Generator>{
      Platform: () => linux,
    });
  });

  test('WebEntrypointTarget generates an entrypoint with plugins and init platform', () => testbed.run(() async {
    final File mainFile = globals.fs.file(globals.fs.path.join('foo', 'lib', 'main.dart'))
      ..createSync(recursive: true)
      ..writeAsStringSync('void main() {}');
    environment.defines[kTargetFile] = mainFile.path;
    environment.defines[kHasWebPlugins] = 'true';
    await const WebEntrypointTarget().build(environment);

    final String generated = environment.buildDir.childFile('main.dart').readAsStringSync();

    // Plugins
    expect(generated, contains("import 'web_plugin_registrant.dart' as pluginRegistrant;"));
    expect(generated, contains('pluginRegistrant.registerPlugins();'));

    // Import.
    expect(generated, contains("import 'package:foo/main.dart' as entrypoint;"));

    // Main
    expect(generated, contains('ui_web.bootstrapEngine('));
    expect(generated, contains('entrypoint.main as _'));
  }, overrides: <Type, Generator>{
    TemplateRenderer: () => const MustacheTemplateRenderer(),
  }));

  test('version.json is created after release build', () => testbed.run(() async {
    environment.defines[kBuildMode] = 'release';
    final Directory webResources = environment.projectDir.childDirectory('web');
    webResources.childFile('index.html')
        .createSync(recursive: true);
    environment.buildDir.childFile('main.dart.js').createSync();
    await WebReleaseBundle(<WebCompilerConfig>[
      const JsCompilerConfig()
    ]).build(environment);

    expect(environment.outputDir.childFile('version.json'), exists);
  }));

    test('override version values', () => testbed.run(() async {
      environment.defines[kBuildMode] = 'release';
      environment.defines[kBuildName] = '2.0.0';
      environment.defines[kBuildNumber] = '22';
      final Directory webResources = environment.projectDir.childDirectory('web');
      webResources.childFile('index.html').createSync(recursive: true);
      environment.buildDir.childFile('main.dart.js').createSync();
      await WebReleaseBundle(<WebCompilerConfig>[
        const JsCompilerConfig()
      ]).build(environment);

      final String versionFile = environment.outputDir
          .childFile('version.json')
          .readAsStringSync();
      expect(versionFile, contains('"version":"2.0.0"'));
      expect(versionFile, contains('"build_number":"22"'));
    }));

  test('Base href is created in index.html with given base-href after release build', () => testbed.run(() async {
    environment.defines[kBuildMode] = 'release';
    environment.defines[kBaseHref] = '/basehreftest/';
    final Directory webResources = environment.projectDir.childDirectory('web');
    webResources.childFile('index.html').createSync(recursive: true);
    webResources.childFile('index.html').writeAsStringSync('''
<!DOCTYPE html><html><base href="$kBaseHrefPlaceholder"><head></head></html>
    ''');
    environment.buildDir.childFile('main.dart.js').createSync();
    await WebTemplatedFiles('buildConfig').build(environment);

    expect(environment.outputDir.childFile('index.html').readAsStringSync(), contains('/basehreftest/'));
  }));

  test('null base href does not override existing base href in index.html', () => testbed.run(() async {
    environment.defines[kBuildMode] = 'release';
    final Directory webResources = environment.projectDir.childDirectory('web');
    webResources.childFile('index.html').createSync(recursive: true);
    webResources.childFile('index.html').writeAsStringSync('''
<!DOCTYPE html><html><head><base href='/basehreftest/'></head></html>
    ''');
    environment.buildDir.childFile('main.dart.js').createSync();
    await WebTemplatedFiles('build config').build(environment);

    expect(environment.outputDir.childFile('index.html').readAsStringSync(), contains('/basehreftest/'));
  }));

  test('WebReleaseBundle copies dart2js output and resource files to output directory', () => testbed.run(() async {
    environment.defines[kBuildMode] = 'release';
    final Directory webResources = environment.projectDir.childDirectory('web');
    webResources.childFile('foo.txt')
      ..createSync(recursive: true)
      ..writeAsStringSync('A');
    environment.buildDir.childFile('main.dart.js').createSync();
    environment.buildDir.childFile('main.dart.js.map').createSync();
    environment.buildDir.childFile('main.dart.js_1.part.js').createSync();
    environment.buildDir.childFile('main.dart.js_1.part.js.map').createSync();

    await WebReleaseBundle(<WebCompilerConfig>[
        const JsCompilerConfig()
    ]).build(environment);

    expect(environment.outputDir.childFile('foo.txt')
      .readAsStringSync(), 'A');
    expect(environment.outputDir.childFile('main.dart.js')
      .existsSync(), true);
    expect(environment.outputDir.childFile('main.dart.js.map')
      .existsSync(), true);
    expect(environment.outputDir.childFile('main.dart.js_1.part.js')
      .existsSync(), true);
    expect(environment.outputDir.childFile('main.dart.js_1.part.js.map')
      .existsSync(), true);
    expect(environment.outputDir.childDirectory('assets')
      .childFile('AssetManifest.bin.json').existsSync(), true);

    // Update to arbitrary resource file triggers rebuild.
    webResources.childFile('foo.txt').writeAsStringSync('B');

    await WebReleaseBundle(<WebCompilerConfig>[
        const JsCompilerConfig()
    ]).build(environment);

    expect(environment.outputDir.childFile('foo.txt')
      .readAsStringSync(), 'B');
  }));

  test('WebReleaseBundle copies over output files when they change', () => testbed.run(() async {
    final Directory webResources = environment.projectDir.childDirectory('web');
    webResources.childFile('foo.txt')
      ..createSync(recursive: true)
      ..writeAsStringSync('A');

    environment.buildDir.childFile('main.dart.wasm')..createSync()..writeAsStringSync('old wasm');
    environment.buildDir.childFile('main.dart.mjs')..createSync()..writeAsStringSync('old mjs');
    await WebReleaseBundle(<WebCompilerConfig>[
      const WasmCompilerConfig()
    ]).build(environment);
    expect(environment.outputDir.childFile('main.dart.wasm')
      .readAsStringSync(), 'old wasm');
        expect(environment.outputDir.childFile('main.dart.mjs')
      .readAsStringSync(), 'old mjs');

    environment.buildDir.childFile('main.dart.wasm')..createSync()..writeAsStringSync('new wasm');
    environment.buildDir.childFile('main.dart.mjs')..createSync()..writeAsStringSync('new mjs');

    await WebReleaseBundle(<WebCompilerConfig>[
      const WasmCompilerConfig()
    ]).build(environment);

    expect(environment.outputDir.childFile('main.dart.wasm')
      .readAsStringSync(), 'new wasm');
    expect(environment.outputDir.childFile('main.dart.mjs')
      .readAsStringSync(), 'new mjs');
  }));

  test('WebEntrypointTarget generates an entrypoint for a file outside of main', () => testbed.run(() async {
    final File mainFile = globals.fs.file(globals.fs.path.join('other', 'lib', 'main.dart'))
      ..createSync(recursive: true)
      ..writeAsStringSync('void main() {}');
    environment.defines[kTargetFile] = mainFile.path;
    await const WebEntrypointTarget().build(environment);

    final String generated = environment.buildDir.childFile('main.dart').readAsStringSync();

    // Import.
    expect(generated, contains("import 'file:///other/lib/main.dart' as entrypoint;"));
  }, overrides: <Type, Generator>{
    TemplateRenderer: () => const MustacheTemplateRenderer(),
  }));

  test('WebEntrypointTarget generates a plugin registrant for a file outside of main', () => testbed.run(() async {
    final File mainFile = globals.fs.file(globals.fs.path.join('other', 'lib', 'main.dart'))
      ..createSync(recursive: true)
      ..writeAsStringSync('void main() {}');
    environment.defines[kTargetFile] = mainFile.path;
    environment.defines[kHasWebPlugins] = 'true';
    await const WebEntrypointTarget().build(environment);

    final String generated = environment.buildDir.childFile('main.dart').readAsStringSync();

    // Import.
    expect(generated, contains("import 'file:///other/lib/main.dart' as entrypoint;"));
    expect(generated, contains("import 'web_plugin_registrant.dart' as pluginRegistrant;"));
  }, overrides: <Type, Generator>{
    TemplateRenderer: () => const MustacheTemplateRenderer(),
  }));


  test('WebEntrypointTarget generates an entrypoint with plugins and init platform on windows', () => testbed.run(() async {
    final File mainFile = globals.fs.file(globals.fs.path.join('foo', 'lib', 'main.dart'))
      ..createSync(recursive: true)
      ..writeAsStringSync('void main() {}');
    environment.defines[kTargetFile] = mainFile.path;

    environment.defines[kHasWebPlugins] = 'true';
    await const WebEntrypointTarget().build(environment);

    final String generated = environment.buildDir.childFile('main.dart').readAsStringSync();

    // Plugins
    expect(generated, contains("import 'web_plugin_registrant.dart' as pluginRegistrant;"));
    expect(generated, contains('pluginRegistrant.registerPlugins();'));

    // Import.
    expect(generated, contains("import 'package:foo/main.dart' as entrypoint;"));

    // Main
    expect(generated, contains('ui_web.bootstrapEngine('));
    expect(generated, contains('entrypoint.main as _'));
  }, overrides: <Type, Generator>{
    Platform: () => windows,
    TemplateRenderer: () => const MustacheTemplateRenderer(),
  }));

  test('WebEntrypointTarget generates an entrypoint without plugins and init platform', () => testbed.run(() async {
    final File mainFile = globals.fs.file(globals.fs.path.join('foo', 'lib', 'main.dart'))
      ..createSync(recursive: true)
      ..writeAsStringSync('void main() {}');
    environment.defines[kTargetFile] = mainFile.path;
    environment.defines[kHasWebPlugins] = 'false';
    await const WebEntrypointTarget().build(environment);

    final String generated = environment.buildDir.childFile('main.dart').readAsStringSync();

    // Plugins (the generated file is a noop)
    expect(generated, contains("import 'web_plugin_registrant.dart' as pluginRegistrant;"));
    expect(generated, contains('pluginRegistrant.registerPlugins();'));

    // Import.
    expect(generated, contains("import 'package:foo/main.dart' as entrypoint;"));

    // Main
    expect(generated, contains('ui_web.bootstrapEngine('));
    expect(generated, contains('entrypoint.main as _'));
  }, overrides: <Type, Generator>{
    TemplateRenderer: () => const MustacheTemplateRenderer(),
  }));

  test('WebEntrypointTarget generates an entrypoint with a language version', () => testbed.run(() async {
    final File mainFile = globals.fs.file(globals.fs.path.join('foo', 'lib', 'main.dart'))
      ..createSync(recursive: true)
      ..writeAsStringSync('// @dart=2.8\nvoid main() {}');
    environment.defines[kTargetFile] = mainFile.path;
    await const WebEntrypointTarget().build(environment);

    final String generated = environment.buildDir.childFile('main.dart').readAsStringSync();

    // Language version
    expect(generated, contains('// @dart=2.8'));
  }, overrides: <Type, Generator>{
    TemplateRenderer: () => const MustacheTemplateRenderer(),
  }));

  test('WebEntrypointTarget generates an entrypoint with a language version from a package config', () => testbed.run(() async {
    final File mainFile = globals.fs.file(globals.fs.path.join('foo', 'lib', 'main.dart'))
      ..createSync(recursive: true)
      ..writeAsStringSync('void main() {}');
    globals.fs.file(globals.fs.path.join('pubspec.yaml'))
      .writeAsStringSync('name: foo\n');
    environment.defines[kTargetFile] = mainFile.path;
    await const WebEntrypointTarget().build(environment);

    final String generated = environment.buildDir.childFile('main.dart').readAsStringSync();

    // Language version
    expect(generated, contains('// @dart=2.7'));
  }, overrides: <Type, Generator>{
    TemplateRenderer: () => const MustacheTemplateRenderer(),
  }));

  test('WebEntrypointTarget generates an entrypoint without plugins and without init platform', () => testbed.run(() async {
    final File mainFile = globals.fs.file(globals.fs.path.join('foo', 'lib', 'main.dart'))
      ..createSync(recursive: true)
      ..writeAsStringSync('void main() {}');
    environment.defines[kTargetFile] = mainFile.path;
    environment.defines[kHasWebPlugins] = 'false';
    await const WebEntrypointTarget().build(environment);

    final String generated = environment.buildDir.childFile('main.dart').readAsStringSync();

    // Plugins
    expect(generated, contains("import 'web_plugin_registrant.dart' as pluginRegistrant;"));
    expect(generated, contains('pluginRegistrant.registerPlugins();'));

    // Import.
    expect(generated, contains("import 'package:foo/main.dart' as entrypoint;"));

    // Main
    expect(generated, contains('ui_web.bootstrapEngine('));
    expect(generated, contains('entrypoint.main as _'));
  }, overrides: <Type, Generator>{
    TemplateRenderer: () => const MustacheTemplateRenderer(),
  }));

  test('Dart2JSTarget calls dart2js with expected args with csp', () => testbed.run(() async {
    environment.defines[kBuildMode] = 'profile';
    environment.defines[JsCompilerConfig.kCspMode] = 'true';
    processManager.addCommand(FakeCommand(
      command: <String>[
        ..._kDart2jsLinuxArgs,
        '-Ddart.vm.profile=true',
        '-DFLUTTER_WEB_AUTO_DETECT=true',
        '--no-source-maps',
        '-o',
        environment.buildDir.childFile('app.dill').absolute.path,
        '--packages=.dart_tool/package_config.json',
        '--cfe-only',
        environment.buildDir.childFile('main.dart').absolute.path,
      ]
    ));
    processManager.addCommand(FakeCommand(
      command: <String>[
        ..._kDart2jsLinuxArgs,
        '-Ddart.vm.profile=true',
        '-DFLUTTER_WEB_AUTO_DETECT=true',
        '--no-minify',
        '--no-source-maps',
        '-O4',
        '--csp',
        '-o',
        environment.buildDir.childFile('main.dart.js').absolute.path,
        environment.buildDir.childFile('app.dill').absolute.path,
      ]
    ));

    await Dart2JSTarget(
      const JsCompilerConfig(
          csp: true,
          sourceMaps: false,
      )
    ).build(environment);
  }, overrides: <Type, Generator>{
    ProcessManager: () => processManager,
  }));

  test('Dart2JSTarget ignores frontend server starter path option when calling dart2js', () => testbed.run(() async {
    environment.defines[kBuildMode] = 'profile';
    environment.defines[kFrontendServerStarterPath] = 'path/to/frontend_server_starter.dart';
    processManager.addCommand(FakeCommand(
      command: <String>[
        ..._kDart2jsLinuxArgs,
        '-Ddart.vm.profile=true',
        '-DFLUTTER_WEB_AUTO_DETECT=true',
        '--no-source-maps',
        '-o',
        environment.buildDir.childFile('app.dill').absolute.path,
        '--packages=.dart_tool/package_config.json',
        '--cfe-only',
        environment.buildDir.childFile('main.dart').absolute.path,
      ]
    ));
    processManager.addCommand(FakeCommand(
      command: <String>[
        ..._kDart2jsLinuxArgs,
        '-Ddart.vm.profile=true',
        '-DFLUTTER_WEB_AUTO_DETECT=true',
        '--no-minify',
        '--no-source-maps',
        '-O4',
        '-o',
        environment.buildDir.childFile('main.dart.js').absolute.path,
        environment.buildDir.childFile('app.dill').absolute.path,
      ]
    ));

    await Dart2JSTarget(
      const JsCompilerConfig(
        sourceMaps: false,
      )
    ).build(environment);
  }, overrides: <Type, Generator>{
    ProcessManager: () => processManager,
  }));

  test('Dart2JSTarget calls dart2js with expected args with enabled experiment', () => testbed.run(() async {
    environment.defines[kBuildMode] = 'profile';
    environment.defines[kExtraFrontEndOptions] = '--enable-experiment=non-nullable';
    processManager.addCommand(FakeCommand(
      command: <String>[
        ..._kDart2jsLinuxArgs,
        '--enable-experiment=non-nullable',
        '-Ddart.vm.profile=true',
        '-DFLUTTER_WEB_AUTO_DETECT=true',
        '--no-source-maps',
        '-o',
        environment.buildDir.childFile('app.dill').absolute.path,
        '--packages=.dart_tool/package_config.json',
        '--cfe-only',
        environment.buildDir.childFile('main.dart').absolute.path,
      ]
    ));
    processManager.addCommand(FakeCommand(
      command: <String>[
        ..._kDart2jsLinuxArgs,
        '--enable-experiment=non-nullable',
        '-Ddart.vm.profile=true',
        '-DFLUTTER_WEB_AUTO_DETECT=true',
        '--no-minify',
        '--no-source-maps',
        '-O4',
        '-o',
        environment.buildDir.childFile('main.dart.js').absolute.path,
        environment.buildDir.childFile('app.dill').absolute.path,
      ]
    ));

    await Dart2JSTarget(
      const JsCompilerConfig(
        sourceMaps: false,
      )
    ).build(environment);
  }, overrides: <Type, Generator>{
    ProcessManager: () => processManager,
  }));

  test('Dart2JSTarget calls dart2js with expected args in profile mode', () => testbed.run(() async {
    environment.defines[kBuildMode] = 'profile';
    processManager.addCommand(FakeCommand(
      command: <String>[
        ..._kDart2jsLinuxArgs,
        '-Ddart.vm.profile=true',
        '-DFLUTTER_WEB_AUTO_DETECT=true',
        '--no-source-maps',
        '-o',
        environment.buildDir.childFile('app.dill').absolute.path,
        '--packages=.dart_tool/package_config.json',
        '--cfe-only',
        environment.buildDir.childFile('main.dart').absolute.path,
      ]
    ));
    processManager.addCommand(FakeCommand(
      command: <String>[
        ..._kDart2jsLinuxArgs,
        '-Ddart.vm.profile=true',
        '-DFLUTTER_WEB_AUTO_DETECT=true',
        '--no-minify',
        '--no-source-maps',
        '-O4',
        '-o',
        environment.buildDir.childFile('main.dart.js').absolute.path,
        environment.buildDir.childFile('app.dill').absolute.path,
      ]
    ));

    await Dart2JSTarget(
      const JsCompilerConfig(
        sourceMaps: false,
      )
    ).build(environment);
  }, overrides: <Type, Generator>{
    ProcessManager: () => processManager,
  }));

  test('Dart2JSTarget calls dart2js with expected args in release mode', () => testbed.run(() async {
    environment.defines[kBuildMode] = 'release';
    processManager.addCommand(FakeCommand(
      command: <String>[
        ..._kDart2jsLinuxArgs,
        '-Ddart.vm.product=true',
        '-DFLUTTER_WEB_AUTO_DETECT=true',
        '--no-source-maps',
        '-o',
        environment.buildDir.childFile('app.dill').absolute.path,
        '--packages=.dart_tool/package_config.json',
        '--cfe-only',
        environment.buildDir.childFile('main.dart').absolute.path,
      ]
    ));
    processManager.addCommand(FakeCommand(
      command: <String>[
        ..._kDart2jsLinuxArgs,
        '-Ddart.vm.product=true',
        '-DFLUTTER_WEB_AUTO_DETECT=true',
        '--no-source-maps',
        '-O4',
        '-o',
        environment.buildDir.childFile('main.dart.js').absolute.path,
        environment.buildDir.childFile('app.dill').absolute.path,
      ]
    ));

    await Dart2JSTarget(
      const JsCompilerConfig(
        sourceMaps: false,
      )
    ).build(environment);
  }, overrides: <Type, Generator>{
    ProcessManager: () => processManager,
  }));

  test('Dart2JSTarget calls dart2js with expected args in release mode with native null assertions', () => testbed.run(() async {
    environment.defines[kBuildMode] = 'release';
    environment.defines[JsCompilerConfig.kNativeNullAssertions] = 'true';
    processManager.addCommand(FakeCommand(
      command: <String>[
        ..._kDart2jsLinuxArgs,
        '-Ddart.vm.product=true',
        '-DFLUTTER_WEB_AUTO_DETECT=true',
        '--native-null-assertions',
        '--no-source-maps',
        '-o',
        environment.buildDir.childFile('app.dill').absolute.path,
        '--packages=.dart_tool/package_config.json',
        '--cfe-only',
        environment.buildDir.childFile('main.dart').absolute.path,
      ]
    ));
    processManager.addCommand(FakeCommand(
      command: <String>[
        ..._kDart2jsLinuxArgs,
        '-Ddart.vm.product=true',
        '-DFLUTTER_WEB_AUTO_DETECT=true',
        '--native-null-assertions',
        '--no-source-maps',
        '-O4',
        '-o',
        environment.buildDir.childFile('main.dart.js').absolute.path,
        environment.buildDir.childFile('app.dill').absolute.path,
      ]
    ));

    await Dart2JSTarget(
      const JsCompilerConfig(
        nativeNullAssertions: true,
        sourceMaps: false,
      )
    ).build(environment);
  }, overrides: <Type, Generator>{
    ProcessManager: () => processManager,
  }));

  test('Dart2JSTarget calls dart2js with expected args in release with dart2js optimization override', () => testbed.run(() async {
    environment.defines[kBuildMode] = 'release';
    processManager.addCommand(FakeCommand(
      command: <String>[
        ..._kDart2jsLinuxArgs,
        '-Ddart.vm.product=true',
        '-DFLUTTER_WEB_AUTO_DETECT=true',
        '--no-source-maps',
        '-o',
        environment.buildDir.childFile('app.dill').absolute.path,
        '--packages=.dart_tool/package_config.json',
        '--cfe-only',
        environment.buildDir.childFile('main.dart').absolute.path,
      ]
    ));
    processManager.addCommand(FakeCommand(
      command: <String>[
        ..._kDart2jsLinuxArgs,
        '-Ddart.vm.product=true',
        '-DFLUTTER_WEB_AUTO_DETECT=true',
        '--no-source-maps',
        '-O3',
        '-o',
        environment.buildDir.childFile('main.dart.js').absolute.path,
        environment.buildDir.childFile('app.dill').absolute.path,
      ]
    ));

    await Dart2JSTarget(
      const JsCompilerConfig(
        optimizationLevel: 3,
        sourceMaps: false,
      )
    ).build(environment);
  }, overrides: <Type, Generator>{
    ProcessManager: () => processManager,
  }));

  test('Dart2JSTarget produces expected depfile', () => testbed.run(() async {
    environment.defines[kBuildMode] = 'release';
    processManager.addCommand(FakeCommand(
      command: <String>[
        ..._kDart2jsLinuxArgs,
        '-Ddart.vm.product=true',
        '-DFLUTTER_WEB_AUTO_DETECT=true',
        '--no-source-maps',
        '-o',
        environment.buildDir.childFile('app.dill').absolute.path,
        '--packages=.dart_tool/package_config.json',
        '--cfe-only',
        environment.buildDir.childFile('main.dart').absolute.path,
      ], onRun: (_) {
        environment.buildDir.childFile('app.dill.deps')
          .writeAsStringSync('file:///a.dart');
      },
    ));
    processManager.addCommand(FakeCommand(
      command: <String>[
        ..._kDart2jsLinuxArgs,
        '-Ddart.vm.product=true',
        '-DFLUTTER_WEB_AUTO_DETECT=true',
        '--no-source-maps',
        '-O4',
        '-o',
        environment.buildDir.childFile('main.dart.js').absolute.path,
        environment.buildDir.childFile('app.dill').absolute.path,
      ]
    ));

    await Dart2JSTarget(
      const JsCompilerConfig(
        sourceMaps: false,
      )
    ).build(environment);

    expect(environment.buildDir.childFile('dart2js.d'), exists);
    final Depfile depfile = environment.depFileService.parse(environment.buildDir.childFile('dart2js.d'));

    expect(depfile.inputs.single.path, globals.fs.path.absolute('a.dart'));
    expect(depfile.outputs.single.path,
      environment.buildDir.childFile('main.dart.js').absolute.path);
  }, overrides: <Type, Generator>{
    ProcessManager: () => processManager,
  }));

  test('Dart2JSTarget calls dart2js with Dart defines in release mode', () => testbed.run(() async {
    environment.defines[kBuildMode] = 'release';
    environment.defines[kDartDefines] = encodeDartDefines(<String>['FOO=bar', 'BAZ=qux']);
    processManager.addCommand(FakeCommand(
      command: <String>[
        ..._kDart2jsLinuxArgs,
        '-Ddart.vm.product=true',
        '-DFOO=bar',
        '-DBAZ=qux',
        '-DFLUTTER_WEB_AUTO_DETECT=true',
        '--no-source-maps',
        '-o',
        environment.buildDir.childFile('app.dill').absolute.path,
        '--packages=.dart_tool/package_config.json',
       '--cfe-only',
        environment.buildDir.childFile('main.dart').absolute.path,
      ]
    ));
    processManager.addCommand(FakeCommand(
      command: <String>[
        ..._kDart2jsLinuxArgs,
        '-Ddart.vm.product=true',
        '-DFOO=bar',
        '-DBAZ=qux',
        '-DFLUTTER_WEB_AUTO_DETECT=true',
        '--no-source-maps',
        '-O4',
        '-o',
        environment.buildDir.childFile('main.dart.js').absolute.path,
        environment.buildDir.childFile('app.dill').absolute.path,
      ]
    ));

    await Dart2JSTarget(
      const JsCompilerConfig(
        sourceMaps: false,
      )
    ).build(environment);
  }, overrides: <Type, Generator>{
    ProcessManager: () => processManager,
  }));

  test('Dart2JSTarget can enable source maps', () => testbed.run(() async {
    environment.defines[kBuildMode] = 'release';
    environment.defines[JsCompilerConfig.kSourceMapsEnabled] = 'true';
    processManager.addCommand(FakeCommand(
      command: <String>[
        ..._kDart2jsLinuxArgs,
        '-Ddart.vm.product=true',
        '-DFLUTTER_WEB_AUTO_DETECT=true',
        '-o',
        environment.buildDir.childFile('app.dill').absolute.path,
        '--packages=.dart_tool/package_config.json',
        '--cfe-only',
        environment.buildDir.childFile('main.dart').absolute.path,
      ]
    ));
    processManager.addCommand(FakeCommand(
      command: <String>[
        ..._kDart2jsLinuxArgs,
        '-Ddart.vm.product=true',
        '-DFLUTTER_WEB_AUTO_DETECT=true',
        '-O4',
        '-o',
        environment.buildDir.childFile('main.dart.js').absolute.path,
        environment.buildDir.childFile('app.dill').absolute.path,
      ]
    ));

    await Dart2JSTarget(
      const JsCompilerConfig()
    ).build(environment);
  }, overrides: <Type, Generator>{
    ProcessManager: () => processManager,
  }));


  test('Dart2JSTarget calls dart2js with Dart defines in profile mode', () => testbed.run(() async {
    environment.defines[kBuildMode] = 'profile';
    environment.defines[kDartDefines] = encodeDartDefines(<String>['FOO=bar', 'BAZ=qux']);
    processManager.addCommand(FakeCommand(
      command: <String>[
        ..._kDart2jsLinuxArgs,
        '-Ddart.vm.profile=true',
        '-DFOO=bar',
        '-DBAZ=qux',
        '-DFLUTTER_WEB_AUTO_DETECT=true',
        '--no-source-maps',
        '-o',
        environment.buildDir.childFile('app.dill').absolute.path,
        '--packages=.dart_tool/package_config.json',
        '--cfe-only',
        environment.buildDir.childFile('main.dart').absolute.path,
      ]
    ));
    processManager.addCommand(FakeCommand(
      command: <String>[
        ..._kDart2jsLinuxArgs,
        '-Ddart.vm.profile=true',
        '-DFOO=bar',
        '-DBAZ=qux',
        '-DFLUTTER_WEB_AUTO_DETECT=true',
        '--no-minify',
        '--no-source-maps',
        '-O4',
        '-o',
        environment.buildDir.childFile('main.dart.js').absolute.path,
        environment.buildDir.childFile('app.dill').absolute.path,
      ]
    ));

    await Dart2JSTarget(
      const JsCompilerConfig(
        sourceMaps: false,
      )
    ).build(environment);
  }, overrides: <Type, Generator>{
    ProcessManager: () => processManager,
  }));

  test('Dart2JSTarget calls dart2js with expected args with dump-info', () => testbed.run(() async {
    environment.defines[kBuildMode] = 'profile';
    environment.defines[JsCompilerConfig.kDart2jsDumpInfo] = 'true';
    processManager.addCommand(FakeCommand(
      command: <String>[
        ..._kDart2jsLinuxArgs,
        '-Ddart.vm.profile=true',
        '-DFLUTTER_WEB_AUTO_DETECT=true',
        '--no-source-maps',
        '-o',
        environment.buildDir.childFile('app.dill').absolute.path,
        '--packages=.dart_tool/package_config.json',
        '--cfe-only',
        environment.buildDir.childFile('main.dart').absolute.path,
      ]
    ));
    processManager.addCommand(FakeCommand(
      command: <String>[
        ..._kDart2jsLinuxArgs,
        '-Ddart.vm.profile=true',
        '-DFLUTTER_WEB_AUTO_DETECT=true',
        '--no-minify',
        '--no-source-maps',
        '-O4',
        '--dump-info',
        '-o',
        environment.buildDir.childFile('main.dart.js').absolute.path,
        environment.buildDir.childFile('app.dill').absolute.path,
      ]
    ));

    await Dart2JSTarget(
      const JsCompilerConfig(
        dumpInfo: true,
        sourceMaps: false,
      )
    ).build(environment);
  }, overrides: <Type, Generator>{
    ProcessManager: () => processManager,
  }));

  test('Dart2JSTarget calls dart2js with expected args with no-frequency-based-minification', () => testbed.run(() async {
    environment.defines[kBuildMode] = 'profile';
    environment.defines[JsCompilerConfig.kDart2jsNoFrequencyBasedMinification] = 'true';
    processManager.addCommand(FakeCommand(
      command: <String>[
        ..._kDart2jsLinuxArgs,
        '-Ddart.vm.profile=true',
        '-DFLUTTER_WEB_AUTO_DETECT=true',
        '--no-source-maps',
        '-o',
        environment.buildDir.childFile('app.dill').absolute.path,
        '--packages=.dart_tool/package_config.json',
        '--cfe-only',
        environment.buildDir.childFile('main.dart').absolute.path,
      ]
    ));
    processManager.addCommand(FakeCommand(
      command: <String>[
        ..._kDart2jsLinuxArgs,
        '-Ddart.vm.profile=true',
        '-DFLUTTER_WEB_AUTO_DETECT=true',
        '--no-minify',
        '--no-source-maps',
        '-O4',
        '--no-frequency-based-minification',
        '-o',
        environment.buildDir.childFile('main.dart.js').absolute.path,
        environment.buildDir.childFile('app.dill').absolute.path,
      ]
    ));

    await Dart2JSTarget(
      const JsCompilerConfig(
          noFrequencyBasedMinification: true,
          sourceMaps: false,
      )
    ).build(environment);
  }, overrides: <Type, Generator>{
    ProcessManager: () => processManager,
  }));

  for (final WebRendererMode renderer in <WebRendererMode>[WebRendererMode.canvaskit, WebRendererMode.skwasm]) {
    for (int level = 1; level <= 4; level++) {
      for (final bool strip in <bool>[true, false]) {
        for (final List<String> defines in const <List<String>>[<String>[], <String>['FOO=bar', 'BAZ=qux']]) {
          for (final String buildMode in const <String>['profile', 'release']) {
            test('Dart2WasmTarget invokes dart2wasm with renderer=$renderer, -O$level, stripping=$strip, defines=$defines, modeMode=$buildMode', () => testbed.run(() async {
              environment.defines[kBuildMode] = buildMode;
              environment.defines[kDartDefines] = encodeDartDefines(defines);

              final File depFile = environment.buildDir.childFile('dart2wasm.d');

              final File outputJsFile = environment.buildDir.childFile('main.dart.mjs');
              processManager.addCommand(FakeCommand(
                command: <String>[
                  ..._kDart2WasmLinuxArgs,
                  if (renderer == WebRendererMode.skwasm) ...<String>[
                    '--extra-compiler-option=--import-shared-memory',
                    '--extra-compiler-option=--shared-memory-max-pages=32768',
                  ],
                  '-Ddart.vm.${buildMode == 'release' ? 'product' : 'profile' }=true',
                  ...defines.map((String define) => '-D$define'),
                  if (renderer == WebRendererMode.skwasm) ...<String>[
                    '-DFLUTTER_WEB_AUTO_DETECT=false',
                    '-DFLUTTER_WEB_USE_SKIA=false',
                    '-DFLUTTER_WEB_USE_SKWASM=true',
                  ],
                  if (renderer == WebRendererMode.canvaskit) ...<String>[
                    '-DFLUTTER_WEB_AUTO_DETECT=false',
                    '-DFLUTTER_WEB_USE_SKIA=true',
                  ],
                  '--extra-compiler-option=--depfile=${depFile.absolute.path}',
                  '-O$level',
                  if (strip && buildMode == 'release') '--no-name-section' else '--name-section',
                  '-o',
                  environment.buildDir.childFile('main.dart.wasm').absolute.path,
                  environment.buildDir.childFile('main.dart').absolute.path,
                ],
                onRun: (_) => outputJsFile..createSync()..writeAsStringSync('foo'))
              );

              await Dart2WasmTarget(
                WasmCompilerConfig(
                  optimizationLevel: level,
                  stripWasm: strip,
                  renderer: renderer,
                )
              ).build(environment);

              expect(outputJsFile.existsSync(), isTrue);
            }, overrides: <Type, Generator>{
            ProcessManager: () => processManager,
          }));
        }
        }
      }
    }
  }

  test('Dart2JSTarget has unique build keys for compiler configurations', () {
    const List<JsCompilerConfig> testConfigs = <JsCompilerConfig>[
      // Default values
      JsCompilerConfig(),

      // Each individual property being made non-default
      JsCompilerConfig(csp: true),
      JsCompilerConfig(dumpInfo: true),
      JsCompilerConfig(nativeNullAssertions: true),
      JsCompilerConfig(optimizationLevel: 0),
      JsCompilerConfig(noFrequencyBasedMinification: true),
      JsCompilerConfig(sourceMaps: false),
      JsCompilerConfig(renderer: WebRendererMode.canvaskit),

      // All properties non-default
      JsCompilerConfig(
        csp: true,
        dumpInfo: true,
        nativeNullAssertions: true,
        optimizationLevel: 0,
        noFrequencyBasedMinification: true,
        sourceMaps: false,
        renderer: WebRendererMode.canvaskit,
      ),
    ];

    final Iterable<String> buildKeys = testConfigs.map((JsCompilerConfig config) {
      final Dart2JSTarget target = Dart2JSTarget(config);
      return target.buildKey;
    });

    // Make sure all the build keys are unique.
    expect(buildKeys.toSet().length, buildKeys.length);
  });

  test('Dart2Wasm has unique build keys for compiler configurations', () {
    const List<WasmCompilerConfig> testConfigs = <WasmCompilerConfig>[
      // Default values
      WasmCompilerConfig(),

      // Each individual property being made non-default
      WasmCompilerConfig(optimizationLevel: 0),
      WasmCompilerConfig(renderer: WebRendererMode.canvaskit),
      WasmCompilerConfig(stripWasm: false),

      // All properties non-default
      WasmCompilerConfig(
        optimizationLevel: 0,
        stripWasm: false,
        renderer: WebRendererMode.canvaskit,
      ),
    ];

    final Iterable<String> buildKeys = testConfigs.map((WasmCompilerConfig config) {
      final Dart2WasmTarget target = Dart2WasmTarget(config);
      return target.buildKey;
    });

    // Make sure all the build keys are unique.
    expect(buildKeys.toSet().length, buildKeys.length);
  });

  test('Generated service worker is empty with none-strategy', () => testbed.run(() {
    final String fileGeneratorsPath =
        environment.artifacts.getArtifactPath(Artifact.flutterToolsFileGenerators);
    final String result = generateServiceWorker(
      fileGeneratorsPath,
      <String, String>{'/foo': 'abcd'},
      <String>[],
      serviceWorkerStrategy: ServiceWorkerStrategy.none,
    );

    expect(result, '');
  }));

  test('Generated service worker correctly inlines file hashes', () => testbed.run(() {
    final String fileGeneratorsPath =
        environment.artifacts.getArtifactPath(Artifact.flutterToolsFileGenerators);
    final String result = generateServiceWorker(
      fileGeneratorsPath,
      <String, String>{'/foo': 'abcd'},
      <String>[],
      serviceWorkerStrategy: ServiceWorkerStrategy.offlineFirst,
    );

    expect(result, contains('{"/foo": "abcd"};'));
  }));

  test('Generated service worker includes core files', () => testbed.run(() {
    final String fileGeneratorsPath =
        environment.artifacts.getArtifactPath(Artifact.flutterToolsFileGenerators);
    final String result = generateServiceWorker(
      fileGeneratorsPath,
      <String, String>{'/foo': 'abcd'},
      <String>['foo', 'bar'],
      serviceWorkerStrategy: ServiceWorkerStrategy.offlineFirst,
    );

    expect(result, contains('"foo",\n"bar"'));
  }));

  test('WebServiceWorker generates a service_worker for a web resource folder', () => testbed.run(() async {
    environment.outputDir.childDirectory('a').childFile('a.txt')
      ..createSync(recursive: true)
      ..writeAsStringSync('A');
    await WebServiceWorker(globals.fs, <WebCompilerConfig>[
      const JsCompilerConfig()
    ]).build(environment);

    expect(environment.outputDir.childFile('flutter_service_worker.js'), exists);
    // Contains file hash.
    expect(environment.outputDir.childFile('flutter_service_worker.js').readAsStringSync(),
      contains('"a/a.txt": "7fc56270e7a70fa81a5935b72eacbe29"'));
    expect(environment.buildDir.childFile('service_worker.d'), exists);
    // Depends on resource file.
    expect(environment.buildDir.childFile('service_worker.d').readAsStringSync(),
      contains('a/a.txt'));
    // Does NOT contain NOTICES
    expect(environment.outputDir.childFile('flutter_service_worker.js').readAsStringSync(),
      isNot(contains('NOTICES')));
  }));

  test('WebServiceWorker contains baseUrl cache', () => testbed.run(() async {
    environment.outputDir
      .childFile('index.html')
      .createSync(recursive: true);
    environment.outputDir
      .childFile('assets/index.html')
      ..createSync(recursive: true)
      ..writeAsStringSync('A');
    await WebServiceWorker(globals.fs, <WebCompilerConfig>[
      const JsCompilerConfig()
    ]).build(environment);

    expect(environment.outputDir.childFile('flutter_service_worker.js'), exists);
    // Contains the same file hash for both `/` and the root index.html file.
    const String rootIndexHash = 'd41d8cd98f00b204e9800998ecf8427e';
    expect(environment.outputDir.childFile('flutter_service_worker.js').readAsStringSync(),
      contains('"/": "$rootIndexHash"'));
    expect(environment.outputDir.childFile('flutter_service_worker.js').readAsStringSync(),
      contains('"index.html": "$rootIndexHash"'));
    // Make sure `assets/index.html` has a different hash than `index.html`.
    expect(environment.outputDir.childFile('flutter_service_worker.js').readAsStringSync(),
      contains('"assets/index.html": "7fc56270e7a70fa81a5935b72eacbe29"'));
    expect(environment.buildDir.childFile('service_worker.d'), exists);
  }));

  test('WebServiceWorker does not cache source maps', () => testbed.run(() async {
    environment.outputDir
      .childFile('main.dart.js')
      .createSync(recursive: true);
    environment.outputDir
      .childFile('main.dart.js.map')
      .createSync(recursive: true);
    await WebServiceWorker(globals.fs, <WebCompilerConfig>[
      const JsCompilerConfig()
    ]).build(environment);

    // No caching of source maps.
    expect(environment.outputDir.childFile('flutter_service_worker.js').readAsStringSync(),
      isNot(contains('"main.dart.js.map"')));
    // Expected twice, once for RESOURCES and once for CORE.
    expect(environment.outputDir.childFile('flutter_service_worker.js').readAsStringSync(),
      contains('"main.dart.js"'));
  }));

  test('WebBuiltInAssets copies over canvaskit again if the web sdk changes', () => testbed.run(() async {
    final File canvasKitInput = globals.fs.file('bin/cache/flutter_web_sdk/canvaskit/canvaskit.wasm')
      ..createSync(recursive: true);
    canvasKitInput.writeAsStringSync('foo', flush: true);

    await WebBuiltInAssets(globals.fs).build(environment);

    final File canvasKitOutputBefore = environment.outputDir.childDirectory('canvaskit')
      .childFile('canvaskit.wasm');
    expect(canvasKitOutputBefore.existsSync(), true);
    expect(canvasKitOutputBefore.readAsStringSync(), 'foo');

    canvasKitInput.writeAsStringSync('bar', flush: true);

    await WebBuiltInAssets(globals.fs).build(environment);

    final File canvasKitOutputAfter = environment.outputDir.childDirectory('canvaskit')
      .childFile('canvaskit.wasm');
    expect(canvasKitOutputAfter.existsSync(), true);
    expect(canvasKitOutputAfter.readAsStringSync(), 'bar');
  }));
}
