// 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.

// @dart=2.9

import 'dart:async';

import 'package:json_rpc_2/src/server.dart' as json_rpc;
import 'package:sse/src/server/sse_handler.dart';
import 'package:stream_channel/stream_channel.dart';

import 'server_api.dart';

class LoggingMiddlewareSink<S> implements StreamSink<S> {
  LoggingMiddlewareSink(this.sink);

  @override
  void add(S event) {
    print('DevTools SSE response: $event');
    sink.add(event);
  }

  @override
  void addError(Object error, [StackTrace stackTrace]) {
    print('DevTools SSE error response: $error');
    sink.addError(error);
  }

  @override
  Future addStream(Stream<S> stream) {
    return sink.addStream(stream);
  }

  @override
  Future close() => sink.close();

  @override
  Future get done => sink.done;

  final StreamSink sink;
}

/// Represents a DevTools client connection to the DevTools server API.
class DevToolsClient {
  DevToolsClient.fromSSEConnection(
    SseConnection sse,
    bool loggingEnabled,
  ) {
    Stream<String> stream = sse.stream;
    StreamSink sink = sse.sink;

    if (loggingEnabled) {
      stream = stream.map<String>((String e) {
        print('DevTools SSE request: $e');
        return e;
      });
      sink = LoggingMiddlewareSink(sink);
    }

    _server = json_rpc.Server(
      StreamChannel(stream, sink),
      strictProtocolChecks: false,
    );
    _registerJsonRpcMethods();
    _server.listen();
  }

  void _registerJsonRpcMethods() {
    _server.registerMethod('connected', (parameters) {
      // Nothing to do here.
    });

    _server.registerMethod('currentPage', (parameters) {
      // Nothing to do here.
    });

    _server.registerMethod('disconnected', (parameters) {
      // Nothing to do here.
    });

    _server.registerMethod('getPreferenceValue', (parameters) {
      final key = parameters['key'].asString;
      final value = ServerApi.devToolsPreferences.properties[key];
      return value;
    });

    _server.registerMethod('setPreferenceValue', (parameters) {
      final key = parameters['key'].asString;
      final value = parameters['value'].value;
      ServerApi.devToolsPreferences.properties[key] = value;
    });
  }

  json_rpc.Server _server;
}
