// Copyright (c) 2018, 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:convert';

import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
import 'package:analysis_server/lsp_protocol/protocol_special.dart';
import 'package:test/test.dart';

main() {
  group('toJson', () {
    test('returns correct JSON for a union', () {
      final _num = new Either2.t1(1);
      final _string = new Either2.t2('Test');
      expect(json.encode(_num.toJson()), equals('1'));
      expect(json.encode(_string.toJson()), equals('"Test"'));
    });

    test('returns correct output for union types', () {
      final message = new RequestMessage(new Either2.t1(1), "test", "test");
      String output = json.encode(message.toJson());
      expect(output, equals('{"id":1,"method":"test","jsonrpc":"test"}'));
    });

    test('returns correct output for types with lists', () {
      final start = new Position(1, 1);
      final end = new Position(2, 2);
      final range = new Range(start, end);
      final location = new Location('y-uri', range);
      final codeAction = new Diagnostic(
        range,
        DiagnosticSeverity.Error,
        new Either2.t2('test_err'),
        '/tmp/source.dart',
        'err!!',
        [new DiagnosticRelatedInformation(location, 'message')],
      );
      final output = json.encode(codeAction.toJson());
      final expected = '''{
        "range":{
            "start":{"line":1,"character":1},
            "end":{"line":2,"character":2}
        },
        "severity":1,
        "code":"test_err",
        "source":"/tmp/source.dart",
        "message":"err!!",
        "relatedInformation":[
            {
              "location":{
                  "uri":"y-uri",
                  "range":{
                    "start":{"line":1,"character":1},
                    "end":{"line":2,"character":2}
                  }
              },
              "message":"message"
            }
        ]
      }'''
          .replaceAll(new RegExp('[ \n]'), '');
      expect(output, equals(expected));
    });

    test('serialises enums to their underlying values', () {
      final foldingRange =
          new FoldingRange(1, 2, 3, 4, FoldingRangeKind.Comment);
      final output = json.encode(foldingRange.toJson());
      final expected = '''{
        "startLine":1,
        "startCharacter":2,
        "endLine":3,
        "endCharacter":4,
        "kind":"comment"
      }'''
          .replaceAll(new RegExp('[ \n]'), '');
      expect(output, equals(expected));
    });
  });

  group('fromJson', () {
    test('parses JSON for types with unions (left side)', () {
      final input = '{"id":1,"method":"test","jsonrpc":"test"}';
      final message = new RequestMessage.fromJson(jsonDecode(input));
      expect(message.id, equals(new Either2<num, String>.t1(1)));
      expect(message.id.valueEquals(1), isTrue);
      expect(message.jsonrpc, "test");
      expect(message.method, "test");
    });

    test('parses JSON for types with unions (right side)', () {
      final input = '{"id":"one","method":"test","jsonrpc":"test"}';
      final message = new RequestMessage.fromJson(jsonDecode(input));
      expect(message.id, equals(new Either2<num, String>.t2("one")));
      expect(message.id.valueEquals("one"), isTrue);
      expect(message.jsonrpc, "test");
      expect(message.method, "test");
    });
  });

  test('objects with lists and enums can round-trip through to json and back',
      () {
    final obj = new ClientCapabilities(
        new WorkspaceClientCapabilities(
            true,
            false,
            [ResourceOperationKind.Create, ResourceOperationKind.Delete],
            FailureHandlingKind.Undo),
        new TextDocumentClientCapabilities(true, false, true, false),
        null);
    final String json = jsonEncode(obj);
    final restoredObj = new ClientCapabilities.fromJson(jsonDecode(json));

    expect(restoredObj.workspace.applyEdit, equals(obj.workspace.applyEdit));
    expect(restoredObj.workspace.documentChanges,
        equals(obj.workspace.documentChanges));
    expect(restoredObj.workspace.resourceOperations,
        equals(obj.workspace.resourceOperations));
    expect(restoredObj.workspace.failureHandling,
        equals(obj.workspace.failureHandling));
    expect(restoredObj.textDocument.didSave, equals(obj.textDocument.didSave));
    expect(restoredObj.textDocument.dynamicRegistration,
        equals(obj.textDocument.dynamicRegistration));
    expect(
        restoredObj.textDocument.willSave, equals(obj.textDocument.willSave));
    expect(restoredObj.textDocument.willSaveWaitUntil,
        equals(obj.textDocument.willSaveWaitUntil));
    expect(restoredObj.experimental, equals(obj.experimental));
  });
}
