// 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 'package:dwds/src/debugging/remote_debugger.dart';
import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart';

/// A remote debugger with a Webkit Inspection Protocol connection.
class WebkitDebugger implements RemoteDebugger {
  final WipDebugger _wipDebugger;

  /// Null until [close] is called.
  ///
  /// All subsequent calls to [close] will return this future.
  Future<void>? _closed;

  WebkitDebugger(this._wipDebugger);

  @override
  Stream<ConsoleAPIEvent> get onConsoleAPICalled =>
      _wipDebugger.connection.runtime.onConsoleAPICalled;

  @override
  Stream<ExceptionThrownEvent> get onExceptionThrown =>
      _wipDebugger.connection.runtime.onExceptionThrown;

  @override
  Future<WipResponse> sendCommand(
    String command, {
    Map<String, dynamic>? params,
  }) =>
      _wipDebugger.sendCommand(command, params: params);

  @override
  Future<void> close() => _closed ??= _wipDebugger.connection.close();

  @override
  Future<void> disable() => _wipDebugger.disable();

  @override
  Future<void> enable() => _wipDebugger.enable();

  @override
  Future<String> getScriptSource(String scriptId) =>
      _wipDebugger.getScriptSource(scriptId);

  @override
  Future<WipResponse> pause() => _wipDebugger.pause();

  @override
  Future<WipResponse> resume() => _wipDebugger.resume();

  @override
  Future<WipResponse> setPauseOnExceptions(PauseState state) =>
      _wipDebugger.setPauseOnExceptions(state);

  @override
  Future<WipResponse> removeBreakpoint(String breakpointId) =>
      _wipDebugger.removeBreakpoint(breakpointId);

  @override
  Future<WipResponse> stepInto({Map<String, dynamic>? params}) =>
      _wipDebugger.stepInto(params: params);

  @override
  Future<WipResponse> stepOut() => _wipDebugger.stepOut();

  @override
  Future<WipResponse> stepOver({Map<String, dynamic>? params}) =>
      _wipDebugger.stepOver(params: params);

  @override
  Future<WipResponse> enablePage() => _wipDebugger.connection.page.enable();

  @override
  Future<WipResponse> pageReload() => _wipDebugger.connection.page.reload();

  @override
  Future<RemoteObject> evaluate(
    String expression, {
    bool? returnByValue,
    int? contextId,
  }) {
    return _wipDebugger.connection.runtime
        .evaluate(expression, returnByValue: returnByValue);
  }

  @override
  Future<RemoteObject> evaluateOnCallFrame(
    String callFrameId,
    String expression,
  ) {
    return _wipDebugger.connection.debugger
        .evaluateOnCallFrame(callFrameId, expression);
  }

  @override
  Future<List<WipBreakLocation>> getPossibleBreakpoints(WipLocation start) {
    return _wipDebugger.connection.debugger.getPossibleBreakpoints(start);
  }

  @override
  Stream<T> eventStream<T>(String method, WipEventTransformer<T> transformer) =>
      _wipDebugger.eventStream(method, transformer);

  @override
  Stream<GlobalObjectClearedEvent> get onGlobalObjectCleared =>
      _wipDebugger.onGlobalObjectCleared;

  @override
  Stream<DebuggerPausedEvent> get onPaused => _wipDebugger.onPaused;

  @override
  Stream<DebuggerResumedEvent> get onResumed => _wipDebugger.onResumed;

  @override
  Stream<ScriptParsedEvent> get onScriptParsed => _wipDebugger.onScriptParsed;

  @override
  Stream<TargetCrashedEvent> get onTargetCrashed => _wipDebugger.eventStream(
        'Inspector.targetCrashed',
        (WipEvent event) => TargetCrashedEvent(event.json),
      );

  @override
  Map<String, WipScript> get scripts => _wipDebugger.scripts;

  @override
  Stream<WipConnection> get onClose => _wipDebugger.connection.onClose;
}
