// Copyright (c) 2017, 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 'dart:convert';
import 'dart:io';

import 'package:analysis_server_client/analysis_server_client.dart';
import 'package:mockito/mockito.dart';
import 'package:test/test.dart';

void main() {
  Process _process;
  AnalysisServerClient serverWrapper;

  setUp(() async {
    _process = new MockProcess();
    final _mockStdin = new MockStdin();
    serverWrapper = new AnalysisServerClient(_process);
    when(_process.stdin).thenReturn(_mockStdin);
    when(_mockStdin.add).thenReturn(null);
  });

  test('test_listenToOutput_good', () async {
    when(_process.stdout).thenAnswer((_) => _goodMessage());

    final future = serverWrapper.send('blahMethod', null);
    serverWrapper.listenToOutput();

    final response = await future;
    expect(response, new isInstanceOf<Map>());
    final responseAsMap = response as Map;
    expect(responseAsMap['foo'], 'bar');
  });

  test('test_listenToOutput_error', () async {
    when(_process.stdout).thenAnswer((_) => _badMessage());
    final future = serverWrapper.send('blahMethod', null);
    future.catchError((e) {
      expect(e, new isInstanceOf<ServerErrorMessage>());
      final e2 = e as ServerErrorMessage;
      expect(e2.code, 'someErrorCode');
      expect(e2.message, 'something went wrong');
      expect(e2.stackTrace, 'some long stack trace');
    });
    serverWrapper.listenToOutput();
  });

  test('test_listenToOutput_event', () async {
    when(_process.stdout).thenAnswer((_) => _eventMessage());

    void eventHandler(String event, Map<String, Object> params) {
      expect(event, 'fooEvent');
      expect(params.length, 2);
      expect(params['foo'] as String, 'bar');
      expect(params['baz'] as String, 'bang');
    }

    serverWrapper.send('blahMethod', null);
    serverWrapper.listenToOutput(notificationProcessor: eventHandler);
  });
}

final _badErrorMessage = {
  'code': 'someErrorCode',
  'message': 'something went wrong',
  'stackTrace': 'some long stack trace'
};

Stream<List<int>> _badMessage() async* {
  yield utf8.encoder.convert('Observatory listening on foo bar\n');
  final sampleJson = {'id': '0', 'error': _badErrorMessage};
  yield utf8.encoder.convert(json.encode(sampleJson));
}

Stream<List<int>> _eventMessage() async* {
  yield utf8.encoder.convert('Observatory listening on foo bar\n');
  final sampleJson = {
    'event': 'fooEvent',
    'params': {'foo': 'bar', 'baz': 'bang'}
  };
  yield utf8.encoder.convert(json.encode(sampleJson));
}

Stream<List<int>> _goodMessage() async* {
  yield utf8.encoder.convert('Observatory listening on foo bar\n');
  final sampleJson = {
    'id': '0',
    'result': {'foo': 'bar'}
  };
  yield utf8.encoder.convert(json.encode(sampleJson));
}

class MockProcess extends Mock implements Process {}

class MockStdin extends Mock implements List {}
