// Copyright 2019 The Chromium 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 'package:meta/meta.dart';
import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart';

import 'application_package.dart';
import 'asset.dart';
import 'base/common.dart';
import 'base/file_system.dart';
import 'base/logger.dart';
import 'base/terminal.dart';
import 'base/utils.dart';
import 'build_info.dart';
import 'bundle.dart';
import 'dart/package_map.dart';
import 'device.dart';
import 'globals.dart';
import 'project.dart';
import 'resident_runner.dart';
import 'run_hot.dart';
import 'web/asset_server.dart';
import 'web/chrome.dart';
import 'web/compile.dart';

/// A hot-runner which handles browser specific delegation.
class ResidentWebRunner extends ResidentRunner {
  ResidentWebRunner(
    List<FlutterDevice> flutterDevices, {
    String target,
    @required this.flutterProject,
    @required bool ipv6,
    @required DebuggingOptions debuggingOptions,
  }) : super(
          flutterDevices,
          target: target,
          usesTerminalUI: true,
          stayResident: true,
          debuggingOptions: debuggingOptions,
          ipv6: ipv6,
        );

  WebAssetServer _server;
  ProjectFileInvalidator projectFileInvalidator;
  DateTime _lastCompiled;
  WipConnection _connection;
  final FlutterProject flutterProject;

  @override
  Future<int> attach(
      {Completer<DebugConnectionInfo> connectionInfoCompleter,
      Completer<void> appStartedCompleter}) async {
    connectionInfoCompleter?.complete(DebugConnectionInfo());
    setupTerminal();
    final int result = await waitForAppToFinish();
    await cleanupAtFinish();
    return result;
  }

  @override
  Future<void> cleanupAfterSignal() async {
    await _connection.sendCommand('Browser.close');
    _connection = null;
    await _server?.dispose();
  }

  @override
  Future<void> cleanupAtFinish() async {
    await _connection?.sendCommand('Browser.close');
    _connection = null;
    await _server?.dispose();
  }

  @override
  Future<void> handleTerminalCommand(String code) async {
    if (code == 'R') {
      // If hot restart is not supported for all devices, ignore the command.
      if (!canHotRestart) {
        return;
      }
      await restart(fullRestart: true);
    }
  }

  @override
  void printHelp({bool details}) {
    const String fire = '🔥';
    const String rawMessage =
        '  To hot restart (and rebuild state), press "R".';
    final String message = terminal.color(
      fire + terminal.bolden(rawMessage),
      TerminalColor.red,
    );
    const String warning = '👻 ';
    printStatus(warning * 20);
    printStatus('Warning: Flutter\'s support for building web applications is highly experimental.');
    printStatus('For more information see https://github.com/flutter/flutter/issues/34082.');
    printStatus(warning * 20);
    printStatus('');
    printStatus(message);
    const String quitMessage = 'To quit, press "q".';
    printStatus('For a more detailed help message, press "h". $quitMessage');
  }

  @override
  Future<int> run({
    Completer<DebugConnectionInfo> connectionInfoCompleter,
    Completer<void> appStartedCompleter,
    String route,
    bool shouldBuild = true,
  }) async {
    final ApplicationPackage package = await ApplicationPackageFactory.instance.getPackageForPlatform(
      TargetPlatform.web_javascript,
      applicationBinary: null,
    );
    if (package == null) {
      printError('No application found for TargetPlatform.web_javascript');
      return 1;
    }
    if (!fs.isFileSync(mainPath)) {
      String message = 'Tried to run $mainPath, but that file does not exist.';
      if (target == null) {
        message +=
            '\nConsider using the -t option to specify the Dart file to start.';
      }
      printError(message);
      return 1;
    }
    // Start the web compiler and build the assets.
    await webCompilationProxy.initialize(
      projectDirectory: flutterProject.directory,
    );
    _lastCompiled = DateTime.now();
    final AssetBundle assetBundle = AssetBundleFactory.instance.createBundle();
    final int build = await assetBundle.build();
    if (build != 0) {
      throwToolExit('Error: Failed to build asset bundle');
    }
    await writeBundle(fs.directory(getAssetBuildDirectory()), assetBundle.entries);

    // Step 2: Start an HTTP server
    _server = WebAssetServer(flutterProject, target, ipv6);
    await _server.initialize();

    // Step 3: Spawn an instance of Chrome and direct it to the created server.
    final String url = 'http://localhost:${_server.port}';
    final Chrome chrome = await chromeLauncher.launch(url);
    final ChromeTab chromeTab = await chrome.chromeConnection.getTab((ChromeTab chromeTab) {
      return chromeTab.url.contains(url); // we don't care about trailing slashes or #
    });
    _connection = await chromeTab.connect();
    _connection.onClose.listen((WipConnection connection) {
      exit();
    });

    // We don't support the debugging proxy yet.
    appStartedCompleter?.complete();
    return attach(
      connectionInfoCompleter: connectionInfoCompleter,
      appStartedCompleter: appStartedCompleter,
    );
  }

  @override
  Future<OperationResult> restart({
    bool fullRestart = false,
    bool pauseAfterRestart = false,
    String reason,
    bool benchmarkMode = false,
  }) async {
    final Stopwatch timer = Stopwatch()..start();
    final Status status = logger.startProgress(
      'Performing hot restart...',
      timeout: timeoutConfiguration.fastOperation,
      progressId: 'hot.restart',
    );
    OperationResult result = OperationResult.ok;
    try {
      final List<Uri> invalidatedSources = ProjectFileInvalidator.findInvalidated(
        lastCompiled: _lastCompiled,
        urisToMonitor: <Uri>[
          for (FileSystemEntity entity in flutterProject.directory
              .childDirectory('lib')
              .listSync(recursive: true))
            if (entity is File && entity.path.endsWith('.dart')) entity.uri
        ], // Add new class to track this for web.
        packagesPath: PackageMap.globalPackagesPath,
      );
      await webCompilationProxy.invalidate(inputs: invalidatedSources);
      await _connection.sendCommand('Page.reload');
      await Future<void>.delayed(const Duration(milliseconds: 150));
    } catch (err) {
      result = OperationResult(1, err.toString());
    } finally {
      printStatus('Restarted application in ${getElapsedAsMilliseconds(timer.elapsed)}.');
      status.cancel();
    }
    return result;
  }
}
