// Copyright (c) 2014, 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.

library json_rpc_2.test.server.server_test;

import 'dart:convert';

import 'package:unittest/unittest.dart';
import 'package:json_rpc_2/error_code.dart' as error_code;
import 'package:json_rpc_2/json_rpc_2.dart' as json_rpc;

import 'utils.dart';

void main() {
  var server;
  setUp(() => server = new json_rpc.Server());

  test("calls a registered method with the given name", () {
    server.registerMethod('foo', (params) {
      return {'params': params.value};
    });

    expect(server.handleRequest({
      'jsonrpc': '2.0',
      'method': 'foo',
      'params': {'param': 'value'},
      'id': 1234
    }), completion(equals({
      'jsonrpc': '2.0',
      'result': {'params': {'param': 'value'}},
      'id': 1234
    })));
  });

  test("calls a method that takes no parameters", () {
    server.registerMethod('foo', () => 'foo');

    expect(server.handleRequest({
      'jsonrpc': '2.0',
      'method': 'foo',
      'id': 1234
    }), completion(equals({
      'jsonrpc': '2.0',
      'result': 'foo',
      'id': 1234
    })));
  });

  test("a method that takes no parameters rejects parameters", () {
    server.registerMethod('foo', () => 'foo');

    expectErrorResponse(server, {
      'jsonrpc': '2.0',
      'method': 'foo',
      'params': {},
      'id': 1234
    },
        error_code.INVALID_PARAMS,
        'No parameters are allowed for method "foo".');
  });

  test("an unexpected error in a method is captured", () {
    server.registerMethod('foo', () => throw new FormatException('bad format'));

    expect(server.handleRequest({
      'jsonrpc': '2.0',
      'method': 'foo',
      'id': 1234
    }), completion({
      'jsonrpc': '2.0',
      'id': 1234,
      'error': {
        'code': error_code.SERVER_ERROR,
        'message': 'bad format',
        'data': {
          'request': {'jsonrpc': '2.0', 'method': 'foo', 'id': 1234},
          'full': 'FormatException: bad format',
          'stack': new isInstanceOf<String>()
        }
      }
    }));
  });

  test("doesn't return a result for a notification", () {
    server.registerMethod('foo', (args) => 'result');

    expect(server.handleRequest({
      'jsonrpc': '2.0',
      'method': 'foo',
      'params': {}
    }), completion(isNull));
  });

  test("includes the error data in the response", () {
    server.registerMethod('foo', (params) {
      throw new json_rpc.RpcException(5, 'Error message.', data: 'data value');
    });

    expectErrorResponse(server, {
      'jsonrpc': '2.0',
      'method': 'foo',
      'params': {},
      'id': 1234
    },
        5,
        'Error message.',
        data: 'data value');
  });

  group("JSON", () {
    test("handles a request parsed from JSON", () {
      server.registerMethod('foo', (params) {
        return {'params': params.value};
      });

      expect(server.parseRequest(JSON.encode({
        'jsonrpc': '2.0',
        'method': 'foo',
        'params': {'param': 'value'},
        'id': 1234
      })), completion(equals(JSON.encode({
        'jsonrpc': '2.0',
        'result': {'params': {'param': 'value'}},
        'id': 1234
      }))));
    });

    test("handles a notification parsed from JSON", () {
      server.registerMethod('foo', (params) {
        return {'params': params};
      });

      expect(server.parseRequest(JSON.encode({
        'jsonrpc': '2.0',
        'method': 'foo',
        'params': {'param': 'value'}
      })), completion(isNull));
    });

    test("a JSON parse error is rejected", () {
      return server.parseRequest('invalid json {').then((result) {
        expect(JSON.decode(result), {
          'jsonrpc': '2.0',
          'error': {
            'code': error_code.PARSE_ERROR,
            'message': startsWith("Invalid JSON: "),
            'data': {'request': 'invalid json {'}
          },
          'id': null
        });
      });
    });
  });

  group("fallbacks", () {
    test("calls a fallback if no method matches", () {
      server.registerMethod('foo', () => 'foo');
      server.registerMethod('bar', () => 'foo');
      server.registerFallback((params) => {'fallback': params.value});

      expect(server.handleRequest({
        'jsonrpc': '2.0',
        'method': 'baz',
        'params': {'param': 'value'},
        'id': 1234
      }), completion(equals({
        'jsonrpc': '2.0',
        'result': {'fallback': {'param': 'value'}},
        'id': 1234
      })));
    });

    test("calls the first matching fallback", () {
      server.registerFallback((params) =>
          throw new json_rpc.RpcException.methodNotFound(params.method));

      server.registerFallback((params) => 'fallback 2');
      server.registerFallback((params) => 'fallback 3');

      expect(server.handleRequest({
        'jsonrpc': '2.0',
        'method': 'fallback 2',
        'id': 1234
      }), completion(equals({
        'jsonrpc': '2.0',
        'result': 'fallback 2',
        'id': 1234
      })));
    });

    test("an unexpected error in a fallback is captured", () {
      server.registerFallback((_) => throw new FormatException('bad format'));

      expect(server.handleRequest({
        'jsonrpc': '2.0',
        'method': 'foo',
        'id': 1234
      }), completion({
        'jsonrpc': '2.0',
        'id': 1234,
        'error': {
          'code': error_code.SERVER_ERROR,
          'message': 'bad format',
          'data': {
            'request': {'jsonrpc': '2.0', 'method': 'foo', 'id': 1234},
            'full': 'FormatException: bad format',
            'stack': new isInstanceOf<String>()
          }
        }
      }));
    });
  });

  test("disallows multiple methods with the same name", () {
    server.registerMethod('foo', () => null);
    expect(() => server.registerMethod('foo', () => null), throwsArgumentError);
  });
}
