// 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() {
  utils.ensureRunFromSdkBinDart();

  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;

  Future<void> 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('--use-aot-snapshot', () async {
    return runWithLsp(['language-server', '--use-aot-snapshot']);
  });

  test('--use-aot-snapshot --enable-experiment=foo', () async {
    return runWithLsp([
      'language-server',
      '--use-aot-snapshot',
      '--enable-experiment=foo',
    ]);
  });

  test('--no-use-aot-snapshot', () async {
    return runWithLsp(['language-server', '--no-use-aot-snapshot']);
  });

  test('--no-use-aot-snapshot --enable-experiment=foo', () async {
    return runWithLsp([
      'language-server',
      '--no-use-aot-snapshot',
      '--enable-experiment=foo',
    ]);
  });

  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 lspHeaderBodySeparator = '\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(lspHeaderBodySeparator)) {
        final parts = bufferString.split(lspHeaderBodySeparator);
        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;
}
