// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
// for details. 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:async/async.dart';
import 'package:dwds/src/debugging/remote_debugger.dart';
import 'package:logging/logging.dart';

abstract class ExecutionContext {
  /// Returns the context ID that contains the running Dart application,
  /// if available.
  Future<int?> get id;
}

/// The execution context in which to do remote evaluations.
class RemoteDebuggerExecutionContext extends ExecutionContext {
  final RemoteDebugger _remoteDebugger;
  final _logger = Logger('RemoteDebuggerExecutionContext');

  /// Contexts that may contain a Dart application.
  ///
  /// Context can be null if an error has occurred and we cannot detect
  /// and parse the context ID.
  late StreamQueue<int> _contexts;
  final _contextController = StreamController<int>();
  final _seenContexts = <int>[];

  int? _id;

  Future<int?> _lookUpId() async {
    _logger.fine('Looking for Dart execution context...');
    const timeoutInMs = 100;
    while (await _contexts.hasNext.timeout(
      const Duration(milliseconds: timeoutInMs),
      onTimeout: () {
        _logger.warning(
          'Timed out finding an execution context after $timeoutInMs ms.',
        );
        return false;
      },
    )) {
      final context = await _contexts.next;
      _seenContexts.add(context);
      _logger.fine('Checking context id: $context');
      try {
        final result = await _remoteDebugger.sendCommand(
          'Runtime.evaluate',
          params: {
            'expression': r'window["$dartAppInstanceId"];',
            'contextId': context,
          },
        );
        if (result.result?['result']?['value'] != null) {
          _logger.fine('Found dart execution context: $context');
          return context;
        }
      } catch (_) {
        // Errors may be thrown if we attempt to evaluate in a stale a context.
        // Ignore and continue.
        _logger.fine('Stale execution context: $context');
        _seenContexts.remove(context);
      }
    }
    return null;
  }

  @override
  Future<int?> get id async {
    if (_id != null) return _id;

    _id = await _lookUpId();
    if (_id == null) {
      // Add seen contexts back to the queue in case the injected
      // client is still loading, so the next call to `id` succeeds.
      _seenContexts.forEach(_contextController.add);
      _seenContexts.clear();
    }
    return _id;
  }

  RemoteDebuggerExecutionContext(this._id, this._remoteDebugger) {
    _remoteDebugger
        .eventStream('Runtime.executionContextsCleared', (e) => e)
        .listen((_) => _id = null);
    _remoteDebugger
        .eventStream('Runtime.executionContextCreated', (e) {
          // Parse and add the context ID to the stream.
          // If we cannot detect or parse the context ID, add `null` to the stream
          // to indicate an error context - those will be skipped when trying to find
          // the dart context, with a warning.
          final id = e.params?['context']?['id']?.toString();
          final parsedId = id == null ? null : int.parse(id);
          if (id == null) {
            _logger.warning('Cannot find execution context id: $e');
          } else if (parsedId == null) {
            _logger.warning('Cannot parse execution context id: $id');
          }
          return parsedId;
        })
        .listen((e) {
          if (e != null) _contextController.add(e);
        });
    _contexts = StreamQueue(_contextController.stream);
  }
}
