// Copyright 2020 The Dart Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Note: this is a copy from flutter tools, updated to work with dwds tests,
// and some functionality removed (does not support hot reload yet)

import 'dart:async';

import 'package:dwds/asset_reader.dart';
import 'package:dwds/config.dart';
import 'package:dwds/expression_compiler.dart';
import 'package:file/file.dart';
import 'package:logging/logging.dart';
import 'package:test_common/test_sdk_layout.dart';

import 'devfs.dart';
import 'frontend_server_client.dart';

class ResidentWebRunner {
  final _logger = Logger('ResidentWebRunner');

  ResidentWebRunner({
    required this.mainUri,
    required this.urlTunneler,
    required this.projectDirectory,
    required this.packageConfigFile,
    required this.packageUriMapper,
    required this.fileSystemRoots,
    required this.fileSystemScheme,
    required this.outputPath,
    required this.compilerOptions,
    required this.sdkLayout,
    bool verbose = false,
  }) {
    final platformDillUri = Uri.file(sdkLayout.summaryPath);

    generator = ResidentCompiler(
      sdkLayout.sdkDirectory,
      projectDirectory: projectDirectory,
      packageConfigFile: packageConfigFile,
      useDebuggerModuleNames: packageUriMapper.useDebuggerModuleNames,
      platformDill: '$platformDillUri',
      fileSystemRoots: fileSystemRoots,
      fileSystemScheme: fileSystemScheme,
      compilerOptions: compilerOptions,
      sdkLayout: sdkLayout,
      verbose: verbose,
    );
    expressionCompiler = TestExpressionCompiler(generator);
  }

  final UrlEncoder? urlTunneler;
  final Uri mainUri;
  final Uri projectDirectory;
  final Uri packageConfigFile;
  final PackageUriMapper packageUriMapper;
  final String outputPath;
  final List<Uri> fileSystemRoots;
  final String fileSystemScheme;
  final CompilerOptions compilerOptions;
  final TestSdkLayout sdkLayout;

  late ResidentCompiler generator;
  late ExpressionCompiler expressionCompiler;
  ProjectFileInvalidator? _projectFileInvalidator;
  WebDevFS? devFS;
  Uri? uri;

  Future<int> run(
    FileSystem fileSystem, {
    String? hostname,
    required int port,
    required String index,
  }) async {
    _projectFileInvalidator ??= ProjectFileInvalidator(fileSystem: fileSystem);
    devFS ??= WebDevFS(
      fileSystem: fileSystem,
      hostname: hostname ?? 'localhost',
      port: port,
      projectDirectory: projectDirectory,
      packageUriMapper: packageUriMapper,
      index: index,
      urlTunneler: urlTunneler,
      sdkLayout: sdkLayout,
      compilerOptions: compilerOptions,
    );
    uri ??= await devFS!.create();

    final report = await _updateDevFS(
      initialCompile: true,
      fullRestart: false,
      fileServerUri: null,
    );
    if (!report.success) {
      _logger.severe('Failed to compile application.');
      return 1;
    }

    generator.accept();
    return 0;
  }

  Future<int> rerun({
    required bool fullRestart,
    // The uri of the `HttpServer` that handles file requests.
    // TODO(srujzs): This should be the same as the uri of the AssetServer to
    // align with Flutter tools, but currently is not. Delete when that's fixed.
    required Uri fileServerUri,
  }) async {
    final report = await _updateDevFS(
      initialCompile: false,
      fullRestart: fullRestart,
      fileServerUri: fileServerUri,
    );
    if (!report.success) {
      _logger.severe('Failed to compile application.');
      return 1;
    }

    generator.accept();
    return 0;
  }

  Future<UpdateFSReport> _updateDevFS({
    required bool initialCompile,
    required bool fullRestart,
    // The uri of the `TestServer` that handles file requests.
    // TODO(srujzs): This should be the same as the uri of the AssetServer to
    // align with Flutter tools, but currently is not. Delete when that's fixed.
    required Uri? fileServerUri,
  }) async {
    final invalidationResult = await _projectFileInvalidator!.findInvalidated(
      lastCompiled: devFS!.lastCompiled,
      urisToMonitor: devFS!.sources,
      packagesPath: packageConfigFile.toFilePath(),
    );
    final report = await devFS!.update(
      mainUri: mainUri,
      dillOutputPath: outputPath,
      generator: generator,
      invalidatedFiles: invalidationResult.uris!,
      initialCompile: initialCompile,
      fullRestart: fullRestart,
      fileServerUri: fileServerUri,
    );
    return report;
  }

  Future<void> stop() async {
    await generator.shutdown();
    await devFS!.dispose();
  }
}
