// 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 'daemon.dart';
import 'utilites.dart';

/// Hosts a set of commands and events to be used with the Daemon.
abstract class Domain {
  Domain(this.daemon, this.name);

  final Daemon daemon;
  final String name;
  final Map<String, CommandHandler> _handlers = <String, CommandHandler>{};

  void registerHandler(String name, CommandHandler handler) {
    _handlers[name] = handler;
  }

  @override
  String toString() => name;

  void handleCommand(String command, dynamic id, Map<String, dynamic> args) {
    Future<dynamic>.sync(() {
      if (_handlers.containsKey(command)) return _handlers[command]!(args);
      throw ArgumentError('command not understood: $name.$command');
    }).then<dynamic>((dynamic result) {
      if (result == null) {
        _send(<String, dynamic>{'id': id});
      } else {
        _send(<String, dynamic>{'id': id, 'result': toJsonable(result)});
      }
    }).catchError((dynamic error, dynamic trace) {
      _send(<String, dynamic>{
        'id': id,
        'error': toJsonable(error),
        'trace': '$trace',
      });
    });
  }

  void sendEvent(String name, [dynamic args]) {
    var map = <String, dynamic>{'event': name};
    if (args != null) map['params'] = toJsonable(args);
    _send(map);
  }

  void _send(Map<String, dynamic> map) => daemon.send(map);

  void dispose() {}
}

typedef CommandHandler = Future<dynamic> Function(Map<String, dynamic> args);
