// Copyright 2022 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 'dart:convert';
import 'dart:io';

import 'package:browser_launcher/browser_launcher.dart' as bl;
import 'package:dds/devtools_server.dart';
import 'package:devtools_shared/devtools_test_utils.dart';
import 'package:vm_service/vm_service.dart';

import '../../common/test_helper.dart';

const verbose = true;

class DevToolsServerDriver {
  DevToolsServerDriver._(
    this._process,
    this._stdin,
    Stream<String> _stdout,
    Stream<String> _stderr,
  ) : stderr = _stderr.map((line) {
          _trace('<== STDERR $line');
          return line;
        }) {
    // Many tests verify JSON output in stdout but some verify usage output
    // to stdout for invalid args, so split the process stdout into two
    // streams, one as JSON and one raw strings.
    var stdoutRawController = StreamController<String>();
    stdoutRaw = stdoutRawController.stream;
    var stdoutJsonController = StreamController<Map<String, Object?>?>();
    stdout = stdoutJsonController.stream;
    _stdout.listen((line) {
      _trace('<== $line');

      // Send to raw stdout stream.
      stdoutRawController.add(line);

      // If the output is JSON, also send a copy to stdoutJson.
      try {
        var json = jsonDecode(line) as Map<String, Object?>;
        stdoutJsonController.add(json);
      } catch (_) {}
    }, onError: (e, s) {
      stdoutRawController.addError(e, s);
      stdoutJsonController.addError(e, s);
    }, onDone: () {
      stdoutRawController.close();
      stdoutJsonController.close();
    });
  }

  final Process _process;
  late final Stream<Map<String, dynamic>?> stdout;
  late final Stream<String> stdoutRaw;
  final Stream<String> stderr;
  final StringSink _stdin;

  Future<int> get exitCode => _process.exitCode;

  void write(Map<String, dynamic> request) {
    final line = jsonEncode(request);
    _trace('==> $line');
    _stdin.writeln(line);
  }

  static void _trace(String message) {
    if (verbose) {
      print(message);
    }
  }

  bool kill() => _process.kill();

  static Future<DevToolsServerDriver> create({
    int port = 0,
    int? tryPorts,
    List<String> additionalArgs = const [],
  }) async {
    final args = [
      'devtools',
      '--machine',
      '--port',
      '$port',
      ...additionalArgs,
    ];

    if (tryPorts != null) {
      args.addAll(['--try-ports', '$tryPorts']);
    }

    if (useChromeHeadless && headlessModeIsSupported) {
      args.add('--headless');
    }
    final Process process = await Process.start(
      Platform.resolvedExecutable,
      args,
    );

    return DevToolsServerDriver._(
      process,
      process.stdin,
      process.stdout.transform(utf8.decoder).transform(const LineSplitter()),
      process.stderr.transform(utf8.decoder).transform(const LineSplitter()),
    );
  }
}

class DevToolsServerTestController {
  static const defaultDelay = Duration(milliseconds: 500);

  late Uri emptyDartAppRoot;
  late Uri packageWithExtensionsRoot;
  CliAppFixture? _appFixture;
  // ignore: unnecessary_getters_setters
  CliAppFixture get appFixture => _appFixture!;
  set appFixture(CliAppFixture? value) => _appFixture = value;

  late DevToolsServerDriver server;

  final completers = <String, Completer<Map<String, dynamic>>>{};

  /// A broadcast stream controller for streaming events from the server.
  late StreamController<Map<String, dynamic>> eventController;

  /// A broadcast stream of events from the server.
  ///
  /// Listening for "server.started" events on this stream may be unreliable
  /// because it may have occurred before the test starts. Use the
  /// [serverStartedEvent] instead.
  Stream<Map<String, dynamic>> get events => eventController.stream;

  /// Completer that signals when the server started event has been received.
  late Completer<Map<String, dynamic>> serverStartedEvent;

  final Map<String, String> registeredServices = {};

  /// A list of PIDs for Chrome instances spawned by tests that should be
  /// cleaned up.
  final List<int> browserPids = [];

  final List<Directory> _tempDirs = [];

  late StreamSubscription<String> stderrSub;

  late StreamSubscription<Map<String, dynamic>?> stdoutSub;

  Future<void> setUp({bool runPubGet = false, bool withApp = true}) async {
    emptyDartAppRoot =
        resolveTestRelativePath('devtools_server/fixtures/empty_dart_app/');
    packageWithExtensionsRoot = resolveTestRelativePath(
        'devtools_server/fixtures/package_with_extensions/');

    serverStartedEvent = Completer<Map<String, dynamic>>();
    eventController = StreamController<Map<String, dynamic>>.broadcast();

    // Start the command-line server.
    server = await DevToolsServerDriver.create();

    // Fail tests on any stderr.
    stderrSub = server.stderr.listen((text) => throw 'STDERR: $text');
    stdoutSub = server.stdout.listen((map) {
      if (map!.containsKey('id')) {
        if (map.containsKey('result')) {
          completers[map['id']]!.complete(map['result']);
        } else {
          completers[map['id']]!.completeError(map['error']);
        }
      } else if (map.containsKey('event')) {
        if (map['event'] == 'server.started') {
          serverStartedEvent.complete(map);
        }
        eventController.add(map);
      }
    });

    await serverStartedEvent.future;
    if (withApp) {
      await startApp(runPubGet: runPubGet);
    }
  }

  Future<void> tearDown() async {
    browserPids
      ..forEach((pid) => Process.killPid(pid, ProcessSignal.sigkill))
      ..clear();
    for (final tempDir in _tempDirs) {
      try {
        await tempDir.delete(recursive: true);
      } catch (_) {}
    }
    _tempDirs.clear();
    await stdoutSub.cancel();
    await stderrSub.cancel();
    server.kill();
    await _appFixture?.teardown();
  }

  Future<Map<String, dynamic>> sendLaunchDevToolsRequest({
    required bool useVmService,
    String? page,
    bool notify = false,
    bool reuseWindows = false,
  }) async {
    final launchEvent =
        events.where((e) => e['event'] == 'client.launch').first;
    if (useVmService) {
      await appFixture.serviceConnection.callMethod(
        registeredServices[DevToolsServer.launchDevToolsService]!,
        args: {
          'reuseWindows': reuseWindows,
          'page': page,
          'notify': notify,
        },
      );
    } else {
      await send(
        'devTools.launch',
        {
          'vmServiceUri': appFixture.serviceUri.toString(),
          'reuseWindows': reuseWindows,
          'page': page,
        },
      );
    }
    final response = await launchEvent;
    final pid = response['params']['pid'];
    if (pid != null) {
      browserPids.add(pid);
    }
    return response['params'];
  }

  Future<Process> launchChrome(String url) async {
    final tempDir =
        Directory.systemTemp.createTempSync('devtools_chrome_profile');
    _tempDirs.add(tempDir);

    final chromeProcess = await bl.Chrome.start([
      url
    ], args: [
      '--user-data-dir=${tempDir.path}', // Ensures process isolation
      '--no-first-run', // Prevents welcome dialogs
      '--no-default-browser-check', // Prevents default browser prompts
      if (useChromeHeadless && headlessModeIsSupported) ...[
        '--headless',
        '--disable-gpu',
        '--no-sandbox',
      ],
      if (Platform.isMacOS) '--use-mock-keychain',
    ]);

    browserPids.add(chromeProcess.pid);
    chromeProcess.exitCode.then((_) {
      browserPids.remove(chromeProcess.pid);
      if (_tempDirs.remove(tempDir)) {
        try {
          tempDir.deleteSync(recursive: true);
        } catch (_) {}
      }
    });
    return chromeProcess;
  }

  Future<void> runPubGet() async {
    emptyDartAppRoot =
        resolveTestRelativePath('devtools_server/fixtures/empty_dart_app/');
    final pubResult = await Process.run(
        Platform.resolvedExecutable, ['pub', 'get'],
        workingDirectory: emptyDartAppRoot.toFilePath());
    if (pubResult.exitCode != 0) {
      throw 'Failed to run "dart pub get" in test fixture:\n'
              '${utf8.decode(pubResult.stdout)}\n'
              '${utf8.decode(pubResult.stderr)}'
          .trim();
    }
  }

  Future<void> startApp({bool runPubGet = false}) async {
    if (runPubGet) {
      await this.runPubGet();
    }

    final appUri = emptyDartAppRoot.resolveUri(Uri.parse('bin/main.dart'));
    appFixture = await CliAppFixture.create(appUri.toFilePath());

    // Track services method names as they're registered.
    appFixture.serviceConnection
        .onEvent(EventStreams.kService)
        .where((e) => e.kind == EventKind.kServiceRegistered)
        .listen((e) => registeredServices[e.service!] = e.method!);
    await appFixture.serviceConnection.streamListen(EventStreams.kService);
    await appFixture.onAppStarted;
  }

  int nextId = 0;
  Future<Map<String, dynamic>> send(
    String method, [
    Map<String, dynamic>? params,
  ]) {
    final id = (nextId++).toString();
    completers[id] = Completer<Map<String, dynamic>>();
    server.write({'id': id.toString(), 'method': method, 'params': params});
    return completers[id]!.future;
  }

  /// Waits for the server's client list to be updated with the expected state,
  /// and then returns the client list.
  ///
  /// It may take time for the servers client list to be updated as the web app
  /// connects, so this helper just polls and waits for the expected state. If
  /// the expected state is never found, the test will timeout.
  Future<Map<String, dynamic>> waitForClients({
    bool? requiredConnectionState,
    String? requiredPage,
    bool expectNone = false,
    bool useLongTimeout = false,
    Duration delayDuration = defaultDelay,
  }) async {
    late Map<String, dynamic> serverResponse;

    bool isOnPage(client) => client['currentPage'] == requiredPage;
    bool hasConnectionState(client) {
      return requiredConnectionState ?? false
          // If we require a connected client, also require a non-null page.
          // This avoids a race in tests where we may proceed to send messages
          // to a client that is not fully initialized.
          ? (client['hasConnection'] && client['currentPage'] != null)
          : !client['hasConnection'];
    }

    final timeout = useLongTimeout
        ? const Duration(seconds: 120)
        : const Duration(seconds: 30);

    await _waitFor(
      () async {
        // Await a short delay to give the client time to connect.
        await delay();

        serverResponse = await send('client.list');
        final clients = serverResponse['clients'];
        return clients is List &&
            (clients.isEmpty == expectNone) &&
            (requiredPage == null || clients.any(isOnPage)) &&
            (requiredConnectionState == null ||
                clients.any(hasConnectionState));
      },
      delayDuration: delayDuration,
      timeout: timeout,
    );

    return serverResponse;
  }

  Future<void> _waitFor(
    Future<bool> Function() condition, {
    Duration delayDuration = defaultDelay,
    Duration timeout = const Duration(seconds: 30),
  }) async {
    final watch = Stopwatch()..start();
    while (true) {
      if (await condition()) {
        return;
      }
      if (watch.elapsed > timeout) {
        throw TimeoutException('Timed out waiting for condition');
      }
      await delay(duration: delayDuration);
    }
  }
}
