// Copyright (c) 2021, 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:vm_service/vm_service.dart';

class DwdsStats {
  /// The time when the user starts the debugger.
  DateTime? _debuggerStart;
  DateTime? get debuggerStart => _debuggerStart;

  /// The time when dwds launches DevTools.
  DateTime? _devToolsStart;
  DateTime? get devToolsStart => _devToolsStart;

  /// Records and returns weither the debugger is ready.
  bool _isFirstDebuggerReady = true;
  bool get isFirstDebuggerReady {
    final wasReady = _isFirstDebuggerReady;
    _isFirstDebuggerReady = false;
    return wasReady;
  }

  void updateLoadTime(
      {required DateTime debuggerStart, required DateTime devToolsStart}) {
    _debuggerStart = debuggerStart;
    _devToolsStart = devToolsStart;
  }

  DwdsStats();
}

class DwdsEventKind {
  static const String compilerUpdateDependencies =
      'COMPILER_UPDATE_DEPENDENCIES';
  static const String devtoolsLaunch = 'DEVTOOLS_LAUNCH';
  static const String devToolsLoad = 'DEVTOOLS_LOAD';
  static const String debuggerReady = 'DEBUGGER_READY';
  static const String evaluate = 'EVALUATE';
  static const String evaluateInFrame = 'EVALUATE_IN_FRAME';
  static const String fullReload = 'FULL_RELOAD';
  static const String getIsolate = 'GET_ISOLATE';
  static const String getScripts = 'GET_SCRIPTS';
  static const String getSourceReport = 'GET_SOURCE_REPORT';
  static const String getVM = 'GET_VM';
  static const String hotRestart = 'HOT_RESTART';
  static const String httpRequestException = 'HTTP_REQUEST_EXCEPTION';
  static const String resume = 'RESUME';

  DwdsEventKind._();
}

class DwdsEvent {
  final String type;
  final Map<String, dynamic> payload;

  DwdsEvent(this.type, this.payload);

  DwdsEvent.compilerUpdateDependencies(String entrypoint)
      : this(DwdsEventKind.compilerUpdateDependencies, {
          'entrypoint': entrypoint,
        });

  DwdsEvent.devtoolsLaunch() : this(DwdsEventKind.devtoolsLaunch, {});

  DwdsEvent.evaluate(String expression, Response? result)
      : this(DwdsEventKind.evaluate, {
          'expression': expression,
          'success': result != null && result is InstanceRef,
          if (result != null && result is ErrorRef) 'error': result,
        });

  DwdsEvent.evaluateInFrame(String expression, Response? result)
      : this(DwdsEventKind.evaluateInFrame, {
          'expression': expression,
          'success': result != null && result is InstanceRef,
          if (result != null && result is ErrorRef) 'error': result,
        });

  DwdsEvent.getIsolate() : this(DwdsEventKind.getIsolate, {});

  DwdsEvent.getScripts() : this(DwdsEventKind.getScripts, {});

  DwdsEvent.getVM() : this(DwdsEventKind.getVM, {});

  DwdsEvent.resume(String? step)
      : this(DwdsEventKind.resume, {if (step != null) 'step': step});

  DwdsEvent.getSourceReport() : this(DwdsEventKind.getSourceReport, {});

  DwdsEvent.hotRestart() : this(DwdsEventKind.hotRestart, {});

  DwdsEvent.fullReload() : this(DwdsEventKind.fullReload, {});

  DwdsEvent.debuggerReady(int elapsedMilliseconds, String screen)
      : this(DwdsEventKind.debuggerReady, {
          'elapsedMilliseconds': elapsedMilliseconds,
          'screen': screen,
        });

  DwdsEvent.devToolsLoad(int elapsedMilliseconds, String screen)
      : this(DwdsEventKind.devToolsLoad, {
          'elapsedMilliseconds': elapsedMilliseconds,
          'screen': screen,
        });

  DwdsEvent.httpRequestException(String server, String exception)
      : this(DwdsEventKind.httpRequestException, {
          'server': server,
          'exception': exception,
        });

  void addException(dynamic exception) {
    payload['exception'] = exception;
  }

  void addElapsedTime(int elapsedMilliseconds) {
    payload['elapsedMilliseconds'] = elapsedMilliseconds;
  }

  @override
  String toString() {
    return 'TYPE: $type Payload: $payload';
  }
}

final _eventController = StreamController<DwdsEvent>.broadcast();

/// Adds an event to the global [eventStream];
void emitEvent(DwdsEvent event) => _eventController.sink.add(event);

/// A global stream of [DwdsEvent]s.
Stream<DwdsEvent> get eventStream => _eventController.stream;

/// Call [function] and record its execution time.
///
/// Calls [event] to create the event to be recorded,
/// and appends time and exception details to it if
/// available.
Future<T> captureElapsedTime<T>(
    Future<T> Function() function, DwdsEvent Function(T? result) event) async {
  final stopwatch = Stopwatch()..start();
  T? result;
  try {
    return result = await function();
  } catch (e) {
    emitEvent(event(null)
      ..addException(e)
      ..addElapsedTime(stopwatch.elapsedMilliseconds));
    rethrow;
  } finally {
    emitEvent(event(result)..addElapsedTime(stopwatch.elapsedMilliseconds));
  }
}
