// Copyright (c) 2021, 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:test/test.dart';

import '../utils.dart' as utils;

void main() {
  group(
    'language-server',
    defineLanguageServerTests,
    timeout: utils.longTimeout,
    onPlatform: {
      'windows': Skip('https://github.com/dart-lang/sdk/issues/44679'),
    },
  );
}

void defineLanguageServerTests() {
  late utils.TestProject project;
  Process? process;

  tearDown(() async => await project.dispose());

  Future runWithLsp(List<String> args) async {
    project = utils.project();

    process = await project.start(args);

    // Send an LSP init.
    final String message = jsonEncode({
      'jsonrpc': '2.0',
      'id': 1,
      'method': 'initialize',
      'params': {
        'processId': pid,
        'clientInfo': {'name': 'dart-cli-tester'},
        'capabilities': {},
        'rootUri': project.dir.uri.toString(),
      },
    });

    process!.stdin.write('Content-Length: ${message.length}\r\n');
    process!.stdin.write('\r\n');
    process!.stdin.write(message);

    // Expect
    final response = await _readLspMessage(process!.stdout);

    final json = jsonDecode(response);
    expect(json['id'], 1);
    expect(json['result'], isNotNull);
    final result = json['result'];
    expect(result['capabilities'], isNotNull);
    expect(result['serverInfo'], isNotNull);
    final serverInfo = result['serverInfo'];
    expect(serverInfo['name'], isNotEmpty);

    process!.kill();
    process = null;
  }

  test('protocol default', () async {
    return runWithLsp(['language-server']);
  });

  test('protocol lsp', () async {
    return runWithLsp(['language-server', '--protocol=lsp']);
  });

  test('protocol analyzer', () async {
    project = utils.project();

    process = await project.start(['language-server', '--protocol=analyzer']);

    final Stream<String> inStream = process!.stdout
        .transform<String>(utf8.decoder)
        .transform<String>(const LineSplitter());

    final line = await inStream.first;
    final json = jsonDecode(line);

    expect(json['event'], 'server.connected');
    expect(json['params'], isNotNull);
    final params = json['params'];
    expect(params['version'], isNotEmpty);
    expect(params['pid'], isNot(0));

    process!.kill();
    process = null;
  });
}

/// Reads the first LSP message from [stream].
Future<String> _readLspMessage(Stream<List<int>> stream) {
  // Headers are complete if there are 2x '\r\n\'. The '\r' is part of the LSP
  // spec for headers and included on all platforms, not just Windows.
  const lspHeaderBodySeperator = '\r\n\r\n';
  final contentLengthRegExp = RegExp(r'Content-Length: (\d+)\r\n');

  final completer = Completer<String>();
  final buffer = StringBuffer();
  late final StreamSubscription<String> inSubscription;
  inSubscription = stream.transform<String>(utf8.decoder).listen(
    (data) {
      // Collect the output into the buffer.
      buffer.write(data);

      // Check whether the buffer has a complete message.
      final bufferString = buffer.toString();

      // To know if we have a complete message, we need to check we have the
      // headers, extract the content-length, then check we have that many
      // bytes in the body.
      if (bufferString.contains(lspHeaderBodySeperator)) {
        final parts = bufferString.split(lspHeaderBodySeperator);
        final headers = parts[0];
        final body = parts[1];
        final length =
            int.parse(contentLengthRegExp.firstMatch(headers)!.group(1)!);
        // Check if we're already had the full payload.
        if (body.length >= length) {
          completer.complete(body.substring(0, length));
          inSubscription.cancel();
        }
      }
    },
  );

  return completer.future;
}
