// Copyright 2016 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 'base/file_system.dart';
import 'device.dart';
import 'globals.dart';
import 'resident_runner.dart';
import 'tracing.dart';
import 'vmservice.dart';

// TODO(mklim): Test this, flutter/flutter#23031.
class ColdRunner extends ResidentRunner {
  ColdRunner(
    List<FlutterDevice> devices, {
    String target,
    DebuggingOptions debuggingOptions,
    this.traceStartup = false,
    this.awaitFirstFrameWhenTracing = true,
    this.applicationBinary,
    bool ipv6 = false,
    bool stayResident = true,
  }) : super(devices,
             target: target,
             debuggingOptions: debuggingOptions,
             hotMode: false,
             stayResident: stayResident,
             ipv6: ipv6);

  final bool traceStartup;
  final bool awaitFirstFrameWhenTracing;
  final File applicationBinary;
  bool _didAttach = false;

  @override
  bool get canHotReload => false;

  @override
  bool get canHotRestart => false;

  @override
  Future<int> run({
    Completer<DebugConnectionInfo> connectionInfoCompleter,
    Completer<void> appStartedCompleter,
    String route,
  }) async {
    final bool prebuiltMode = applicationBinary != null;
    if (!prebuiltMode) {
      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;
      }
    }

    for (FlutterDevice device in flutterDevices) {
      final int result = await device.runCold(
        coldRunner: this,
        route: route,
      );
      if (result != 0) {
        return result;
      }
    }

    // Connect to observatory.
    if (debuggingOptions.debuggingEnabled) {
      try {
        await connectToServiceProtocol();
      } on String catch (message) {
        printError(message);
        return 2;
      }
    }

    if (flutterDevices.first.observatoryUris != null) {
      // For now, only support one debugger connection.
      connectionInfoCompleter?.complete(DebugConnectionInfo(
        httpUri: flutterDevices.first.vmServices.first.httpAddress,
        wsUri: flutterDevices.first.vmServices.first.wsAddress,
      ));
    }

    printTrace('Application running.');

    for (FlutterDevice device in flutterDevices) {
      if (device.vmServices == null) {
        continue;
      }
      device.initLogReader();
      await device.refreshViews();
      printTrace('Connected to ${device.device.name}');
    }

    if (traceStartup) {
      // Only trace startup for the first device.
      final FlutterDevice device = flutterDevices.first;
      if (device.vmServices != null && device.vmServices.isNotEmpty) {
        printStatus('Tracing startup on ${device.device.name}.');
        await downloadStartupTrace(
          device.vmServices.first,
          awaitFirstFrame: awaitFirstFrameWhenTracing,
        );
      }
      appFinished();
    }

    appStartedCompleter?.complete();

    writeVmserviceFile();

    if (stayResident && !traceStartup) {
      return waitForAppToFinish();
    }
    await cleanupAtFinish();
    return 0;
  }

  @override
  Future<int> attach({
    Completer<DebugConnectionInfo> connectionInfoCompleter,
    Completer<void> appStartedCompleter,
  }) async {
    _didAttach = true;
    try {
      await connectToServiceProtocol();
    } catch (error) {
      printError('Error connecting to the service protocol: $error');
      // https://github.com/flutter/flutter/issues/33050
      // TODO(blasten): Remove this check once https://issuetracker.google.com/issues/132325318 has been fixed.
      if (await hasDeviceRunningAndroidQ(flutterDevices) &&
          error.toString().contains(kAndroidQHttpConnectionClosedExp)) {
        printStatus('🔨 If you are using an emulator running Android Q Beta, consider using an emulator running API level 29 or lower.');
        printStatus('Learn more about the status of this issue on https://issuetracker.google.com/issues/132325318');
      }
      return 2;
    }
    for (FlutterDevice device in flutterDevices) {
      device.initLogReader();
    }
    await refreshViews();
    for (FlutterDevice device in flutterDevices) {
      for (FlutterView view in device.views) {
        printTrace('Connected to $view.');
      }
    }
    appStartedCompleter?.complete();
    if (stayResident) {
      return waitForAppToFinish();
    }
    await cleanupAtFinish();
    return 0;
  }

  @override
  Future<void> cleanupAfterSignal() async {
    await stopEchoingDeviceLog();
    if (_didAttach) {
      appFinished();
    }
    await exitApp();
  }

  @override
  Future<void> cleanupAtFinish() async {
    for (FlutterDevice flutterDevice in flutterDevices) {
      flutterDevice.device.dispose();
    }

    await stopEchoingDeviceLog();
  }

  @override
  void printHelp({ @required bool details }) {
    bool haveDetails = false;
    bool haveAnything = false;
    for (FlutterDevice device in flutterDevices) {
      final String dname = device.device.name;
      if (device.vmServices != null) {
        for (VMService vm in device.vmServices) {
          printStatus('An Observatory debugger and profiler on $dname is available at: ${vm.httpAddress}');
        }
      }
    }
    if (supportsServiceProtocol) {
      haveDetails = true;
      if (details) {
        printHelpDetails();
        haveAnything = true;
      }
    }
    final String quitMessage = _didAttach
      ? 'To detach, press "d"; to quit, press "q".'
      : 'To quit, press "q".';
    if (haveDetails && !details) {
      printStatus('For a more detailed help message, press "h". $quitMessage');
    } else if (haveAnything) {
      printStatus('To repeat this help message, press "h". $quitMessage');
    } else {
      printStatus(quitMessage);
    }
  }

  @override
  Future<void> preExit() async {
    for (FlutterDevice device in flutterDevices) {
      // If we're running in release mode, stop the app using the device logic.
      if (device.vmServices == null || device.vmServices.isEmpty) {
        await device.device.stopApp(device.package);
      }
    }
    await super.preExit();
  }
}
