// 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 services.common_server_api_protobuf_test;

import 'dart:async';
import 'dart:convert';

import 'package:dart_services/src/common.dart';
import 'package:dart_services/src/common_server_impl.dart';
import 'package:dart_services/src/common_server_api.dart';
import 'package:dart_services/src/server_cache.dart';
import 'package:dart_services/src/protos/dart_services.pb.dart' as proto;
import 'package:logging/logging.dart';
import 'package:mock_request/mock_request.dart';
import 'package:protobuf/protobuf.dart';
import 'package:shelf/shelf_io.dart' as shelf_io;
import 'package:test/test.dart';

const quickFixesCode = r'''
import 'dart:async';
void main() {
  int i = 0;
}
''';

const preFormattedCode = r'''
void main()
{
int i = 0;
}
''';

const postFormattedCode = r'''
void main() {
  int i = 0;
}
''';

const formatBadCode = r'''
void main()
{
  print('foo')
}
''';

const assistCode = r'''
main() {
  int v = 0;
}
''';

void main() => defineTests();

void defineTests() {
  CommonServerApi commonServerApi;
  CommonServerImpl commonServerImpl;

  MockContainer container;
  MockCache cache;

  Future<MockHttpResponse> _sendPostRequest(
    String path,
    GeneratedMessage message,
  ) async {
    assert(commonServerApi != null);
    final uri = Uri.parse('/api/$path');
    final request = MockHttpRequest('POST', uri);
    request.headers.add('content-type', JSON_CONTENT_TYPE);
    request.add(utf8.encode(json.encode(message.toProto3Json())));
    await request.close();
    await shelf_io.handleRequest(request, commonServerApi.router);
    return request.response;
  }

  Future<MockHttpResponse> _sendGetRequest(
    String path,
  ) async {
    assert(commonServerApi != null);
    final uri = Uri.parse('/api/$path');
    final request = MockHttpRequest('POST', uri);
    request.headers.add('content-type', JSON_CONTENT_TYPE);
    await request.close();
    await shelf_io.handleRequest(request, commonServerApi.router);
    return request.response;
  }

  group('CommonServerProto JSON', () {
    setUpAll(() async {
      container = MockContainer();
      cache = MockCache();
      commonServerImpl = CommonServerImpl(container, cache);
      commonServerApi = CommonServerApi(commonServerImpl);
      await commonServerImpl.init();

      // Some piece of initialization doesn't always happen fast enough for this
      // request to work in time for the test. So try it here until the server
      // returns something valid.
      // TODO(jcollins-g): determine which piece of initialization isn't
      // happening and deal with that in warmup/init.
      {
        var decodedJson = {};
        final jsonData = proto.SourceRequest()..source = sampleCodeError;
        while (decodedJson.isEmpty) {
          final response =
              await _sendPostRequest('dartservices/v2/analyze', jsonData);
          expect(response.statusCode, 200);
          expect(response.headers['content-type'],
              ['application/json; charset=utf-8']);
          final data = await response.transform(utf8.decoder).join();
          decodedJson = json.decode(data) as Map<dynamic, dynamic>;
        }
      }
    });

    tearDownAll(() async {
      await commonServerImpl.shutdown();
    });

    setUp(() {
      log.onRecord.listen((LogRecord rec) {
        print('${rec.level.name}: ${rec.time}: ${rec.message}');
      });
    });

    tearDown(log.clearListeners);

    test('analyze Dart', () async {
      final request = proto.SourceRequest()..source = sampleCode;
      final response =
          await _sendPostRequest('dartservices/v2/analyze', request);
      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.AnalysisResults()..mergeFromProto3Json(data);
      expect(reply.issues, isEmpty);
      expect(reply.packageImports, isEmpty);
    });

    test('analyze Flutter', () async {
      final request = proto.SourceRequest()..source = sampleCodeFlutter;
      final response =
          await _sendPostRequest('dartservices/v2/analyze', request);
      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.AnalysisResults()..mergeFromProto3Json(data);
      expect(reply.issues, isEmpty);
      expect(reply.packageImports, ['flutter']);
    });

    test('analyze errors', () async {
      final request = proto.SourceRequest()..source = sampleCodeError;
      final response =
          await _sendPostRequest('dartservices/v2/analyze', request);
      expect(response.statusCode, 200);
      expect(response.headers['content-type'],
          ['application/json; charset=utf-8']);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.AnalysisResults()..mergeFromProto3Json(data);
      expect(reply.issues[0].kind, 'error');
      expect(reply.issues[0].line, 2);
      expect(reply.issues[0].sourceName, 'main.dart');
      expect(reply.issues[0].message, "Expected to find ';'.");
      expect(reply.issues[0].hasFixes, true);
      expect(reply.issues[0].charStart, 29);
      expect(reply.issues[0].charLength, 1);
    });

    test('analyze negative-test noSource', () async {
      final request = proto.SourceRequest();
      final response =
          await _sendPostRequest('dartservices/v2/analyze', request);
      expect(response.statusCode, 400);
    });

    test('compile', () async {
      final request = proto.CompileRequest()..source = sampleCode;
      final response =
          await _sendPostRequest('dartservices/v2/compile', request);
      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.CompileResponse()..mergeFromProto3Json(data);
      expect(reply.result, isNotEmpty);
    });

    test('compile error', () async {
      final request = proto.CompileRequest()..source = sampleCodeError;
      final response =
          await _sendPostRequest('dartservices/v2/compile', request);
      expect(response.statusCode, 400);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.CompileResponse()..mergeFromProto3Json(data);
      expect(reply.error.message, contains('Error: Expected'));
    });

    test('compile negative-test noSource', () async {
      final request = proto.CompileRequest();
      final response =
          await _sendPostRequest('dartservices/v2/compile', request);
      expect(response.statusCode, 400);
    });

    test('compileDDC', () async {
      final request = proto.CompileRequest()..source = sampleCode;
      final response =
          await _sendPostRequest('dartservices/v2/compileDDC', request);
      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.CompileDDCResponse()..mergeFromProto3Json(data);
      expect(reply.result, isNotEmpty);
    });

    test('complete', () async {
      final request = proto.SourceRequest()
        ..source = 'void main() {print("foo");}'
        ..offset = 1;
      final response =
          await _sendPostRequest('dartservices/v2/complete', request);
      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.CompleteResponse()..mergeFromProto3Json(data);
      expect(reply.completions, isNotEmpty);
    });

    test('complete no data', () async {
      final request = await _sendPostRequest(
          'dartservices/v2/complete', proto.SourceRequest());
      expect(request.statusCode, 400);
    });

    test('complete param missing', () async {
      final request = proto.SourceRequest()..offset = 1;
      final response =
          await _sendPostRequest('dartservices/v2/complete', request);
      expect(response.statusCode, 400);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.CompleteResponse()..mergeFromProto3Json(data);
      expect(reply.error.message, 'Missing parameter: \'source\'');
    });

    test('complete param missing 2', () async {
      final request = proto.SourceRequest()
        ..source = 'void main() {print("foo");}';
      final response =
          await _sendPostRequest('dartservices/v2/complete', request);
      expect(response.statusCode, 400);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.CompleteResponse()..mergeFromProto3Json(data);
      expect(reply.error.message, 'Missing parameter: \'offset\'');
    });

    test('document', () async {
      final request = proto.SourceRequest()
        ..source = 'void main() {print("foo");}'
        ..offset = 17;
      final response =
          await _sendPostRequest('dartservices/v2/document', request);
      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.DocumentResponse()..mergeFromProto3Json(data);
      expect(reply.info, isNotEmpty);
    });

    test('document little data', () async {
      final request = proto.SourceRequest()
        ..source = 'void main() {print("foo");}'
        ..offset = 2;
      final response =
          await _sendPostRequest('dartservices/v2/document', request);
      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.DocumentResponse()..mergeFromProto3Json(data);
      expect(reply.info, isEmpty);
    });

    test('document no data', () async {
      final request = proto.SourceRequest()
        ..source = 'void main() {print("foo");}'
        ..offset = 12;
      final response =
          await _sendPostRequest('dartservices/v2/document', request);
      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.DocumentResponse()..mergeFromProto3Json(data);
      expect(reply.info, isEmpty);
    });

    test('document negative-test noSource', () async {
      final request = proto.SourceRequest()..offset = 12;
      final response =
          await _sendPostRequest('dartservices/v2/document', request);
      expect(response.statusCode, 400);
    });

    test('document negative-test noOffset', () async {
      final request = proto.SourceRequest()
        ..source = 'void main() {print("foo");}';
      final response =
          await _sendPostRequest('dartservices/v2/document', request);
      expect(response.statusCode, 400);
    });

    test('format', () async {
      final request = proto.SourceRequest()..source = preFormattedCode;
      final response =
          await _sendPostRequest('dartservices/v2/format', request);
      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.FormatResponse()..mergeFromProto3Json(data);
      expect(reply.newString, postFormattedCode);
    });

    test('format bad code', () async {
      final request = proto.SourceRequest()..source = formatBadCode;
      final response =
          await _sendPostRequest('dartservices/v2/format', request);
      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.FormatResponse()..mergeFromProto3Json(data);
      expect(reply.newString, formatBadCode);
    });

    test('format position', () async {
      final request = proto.SourceRequest()
        ..source = preFormattedCode
        ..offset = 21;
      final response =
          await _sendPostRequest('dartservices/v2/format', request);
      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.FormatResponse()..mergeFromProto3Json(data);
      expect(reply.newString, postFormattedCode);
      expect(reply.offset, 24);
    });

    test('fix', () async {
      final request = proto.SourceRequest()
        ..source = quickFixesCode
        ..offset = 10;
      final response = await _sendPostRequest('dartservices/v2/fixes', request);
      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.FixesResponse()..mergeFromProto3Json(data);
      final fixes = reply.fixes;
      expect(fixes.length, 1);
      final problemAndFix = fixes[0];
      expect(problemAndFix.problemMessage, isNotNull);
    });

    test('fixes completeness', () async {
      final request = proto.SourceRequest()
        ..source = '''
void main() {
  for (int i = 0; i < 4; i++) {
    print('hello \$i')
  }
}
'''
        ..offset = 67;
      final response = await _sendPostRequest('dartservices/v2/fixes', request);
      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.FixesResponse()..mergeFromProto3Json(data);
      expect(reply.fixes[0].fixes[0].message, "Insert ';'");
      expect(reply.fixes[0].fixes[0].edits[0].offset, 67);
      expect(reply.fixes[0].fixes[0].edits[0].length, 0);
      expect(reply.fixes[0].fixes[0].edits[0].replacement, ';');
      expect(reply.fixes[0].problemMessage, "Expected to find ';'.");
      expect(reply.fixes[0].offset, 66);
      expect(reply.fixes[0].length, 1);
    });

    test('assist', () async {
      final request = proto.SourceRequest()
        ..source = assistCode
        ..offset = 15;
      final response =
          await _sendPostRequest('dartservices/v2/assists', request);
      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.AssistsResponse()..mergeFromProto3Json(data);
      final assists = reply.assists;
      expect(assists, hasLength(2));
      expect(assists.first.edits, isNotNull);
      expect(assists.first.edits, hasLength(1));
      expect(
          assists.where((candidateFix) =>
              candidateFix.message == 'Remove type annotation'),
          isNotEmpty);
    });

    test('version', () async {
      final response = await _sendGetRequest('dartservices/v2/version');
      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      expect(data['sdkVersion'], isNotNull);
      expect(data['runtimeVersion'], isNotNull);
    });
  });
}

class MockContainer implements ServerContainer {
  @override
  String get version => vmVersion;
}

class MockCache implements ServerCache {
  @override
  Future<String> get(String key) => Future.value(null);

  @override
  Future set(String key, String value, {Duration expiration}) => Future.value();

  @override
  Future remove(String key) => Future.value();

  @override
  Future<void> shutdown() => Future.value();
}
