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

import 'package:dart_services/src/analysis_server.dart';
import 'package:dart_services/src/common.dart';
import 'package:dart_services/src/protos/dart_services.pb.dart' as proto;
import 'package:dart_services/src/sdk.dart';
import 'package:test/test.dart';

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

const completionFilterCode = r'''
void main() {
  pr
}
''';

const completionLargeNamespaces = r'''
class A {}
class AB {}
class ABC {}
void main() {
  var c = A
}
class ZZ {}
class a {}
''';

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

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

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

const formatWithIssues = '''
void main() { foo() }
''';

const lintWarningTrigger = '''
void main() async {
  var unknown;
  print(unknown);
}
''';

final channel = Platform.environment['FLUTTER_CHANNEL'] ?? stableChannel;

void main() => defineTests();

void defineTests() {
  late AnalysisServerWrapper analysisServer;

  /// Returns whether the completion [response] contains [expected].
  bool completionsContains(proto.CompleteResponse response, String expected) =>
      response.completions
          .any((completion) => completion.completion['completion'] == expected);

  group('Platform SDK analysis_server', () {
    late Sdk sdk;
    setUp(() async {
      sdk = Sdk.create(channel);
      analysisServer = DartAnalysisServerWrapper(dartSdkPath: sdk.dartSdkPath);
      await analysisServer.init();
    });

    tearDown(() => analysisServer.shutdown());

    test('simple_completion', () async {
      // Just after `i.` on line 3 of [completionCode]
      final results = await analysisServer.complete(completionCode, 32);
      expect(results.replacementLength, 0);
      expect(results.replacementOffset, 32);
      final completions =
          results.completions.map((c) => c.completion['completion']).toList();
      expect(completions, contains('abs'));
      expect(completionsContains(results, 'codeUnitAt'), false);
    });

    // https://github.com/dart-lang/dart-pad/issues/2005
    test('Trigger lint with Dart code', () async {
      final results = await analysisServer.analyze(lintWarningTrigger);
      expect(results.issues.length, 1);
      final issue = results.issues[0];
      expect(issue.line, 2);
      expect(issue.column, 7);
      expect(issue.kind, 'info');
      expect(issue.message,
          'An uninitialized variable should have an explicit type annotation.');
      expect(issue.code, 'prefer_typing_uninitialized_variables');
    });

    test('repro #126 - completions polluted on second request', () async {
      // https://github.com/dart-lang/dart-services/issues/126
      return analysisServer.complete(completionFilterCode, 17).then((results) {
        return analysisServer
            .complete(completionFilterCode, 17)
            .then((results) {
          expect(results.replacementLength, 2);
          expect(results.replacementOffset, 16);
          expect(completionsContains(results, 'print'), true);
          expect(completionsContains(results, 'pow'), false);
        });
      });
    });

    test('import_test', () async {
      // We're testing here that we don't have any path imports - we don't want
      // to enable browsing the file system.
      final testCode = "import '/'; main() { int a = 0; a. }";
      final results = await analysisServer.complete(testCode, 9);
      final completions = results.completions;

      if (completions.isNotEmpty) {
        expect(completions.every((completion) {
          return completion.completion['completion']!.startsWith('dart:');
        }), true);
      }
    });

    test('import_dart_core_test', () async {
      // Ensure we can import dart: imports.
      final testCode = "import 'dart:c'; main() { int a = 0; a. }";

      final results = await analysisServer.complete(testCode, 14);
      final completions = results.completions;

      expect(
        completions.every((completion) =>
            completion.completion['completion']!.startsWith('dart:')),
        true,
      );
      expect(
        completions.any((completion) =>
            completion.completion['completion']!.startsWith('dart:')),
        true,
      );
    });

    test('import_and_other_test', () async {
      final testCode = "import '/'; main() { int a = 0; a. }";
      final results = await analysisServer.complete(testCode, 34);

      expect(completionsContains(results, 'abs'), true);
    });

    test('simple_quickFix', () async {
      final results = await analysisServer.getFixes(quickFixesCode, 25);

      expect(results.fixes.length, 2);

      // Fixes are not guaranteed to arrive in a particular order.
      results.fixes.sort((a, b) => a.offset.compareTo(b.offset));

      expect(results.fixes[0].offset, 20);
      expect(results.fixes[0].length, 1); // We need an insertion.

      expect(results.fixes[1].offset, 24);
      expect(results.fixes[1].length, 1); // We need an insertion.

      expect(results.fixes[1].fixes.length, 1);

      final candidateFix = results.fixes[1].fixes[0];

      expect(candidateFix.message.contains(';'), true);
      expect(candidateFix.edits[0].length, 0);
      expect(candidateFix.edits[0].offset, 25);
      expect(candidateFix.edits[0].replacement, ';');
    });

    test('simple_format', () async {
      final results = await analysisServer.format(badFormatCode, 0);
      expect(results.newString, formattedCode);
    });

    test('format good code', () async {
      final results =
          await analysisServer.format(formattedCode.replaceAll('\n', ' '), 0);
      expect(results.newString, formattedCode);
    });

    test('format with issues', () async {
      final results = await analysisServer.format(formatWithIssues, 0);
      expect(results.newString, formatWithIssues);
    });

    test('analyze', () async {
      final results = await analysisServer.analyze(sampleCode);
      expect(results.issues, isEmpty);
    });

    test('analyze with errors', () async {
      final results = await analysisServer.analyze(sampleCodeError);
      expect(results.issues, hasLength(1));
    });

    test('filter completions', () async {
      // just after A
      final idx = 61;
      expect(completionLargeNamespaces.substring(idx - 1, idx), 'A');
      final results =
          await analysisServer.complete(completionLargeNamespaces, 61);
      expect(completionsContains(results, 'A'), true);
      expect(completionsContains(results, 'AB'), true);
      expect(completionsContains(results, 'ABC'), true);
      expect(completionsContains(results, 'a'), true);
      expect(completionsContains(results, 'ZZ'), false);
    });
  });

  group('Flutter cached SDK analysis_server', () {
    setUp(() async {
      final sdk = Sdk.create(channel);
      analysisServer =
          FlutterAnalysisServerWrapper(dartSdkPath: sdk.dartSdkPath);
      await analysisServer.init();
    });

    tearDown(() => analysisServer.shutdown());

    test('analyze working Dart code', () async {
      final results = await analysisServer.analyze(sampleCode);
      expect(results.issues, isEmpty);
    });

    test('analyze working Flutter code', () async {
      final results = await analysisServer.analyze(sampleCode);
      expect(results.issues, isEmpty);
    });
  });

  //--------------------------------------------------------
  // Begin testing the multi file group files={} map entry points:
  group('Platform SDK analysis_server multifile files={}', () {
    late Sdk sdk;
    setUp(() async {
      sdk = Sdk.create(channel);
      analysisServer = DartAnalysisServerWrapper(dartSdkPath: sdk.dartSdkPath);
      await analysisServer.init();
    });

    tearDown(() => analysisServer.shutdown());

    // Now test multi file 'files:{}' source format.
    const kMainDart = 'main.dart';

    test('files={} simple_completion', () async {
      // Just after `i.` on line 3 of [completionCode]
      final results = await analysisServer
          .completeFiles({kMainDart: completionCode}, Location(kMainDart, 32));
      expect(results.replacementLength, 0);
      expect(results.replacementOffset, 32);
      final completions =
          results.completions.map((c) => c.completion['completion']).toList();
      expect(completions, contains('abs'));
      expect(completionsContains(results, 'codeUnitAt'), false);
    });

    // https://github.com/dart-lang/dart-pad/issues/2005
    test('files={} Trigger lint with Dart code', () async {
      final results =
          await analysisServer.analyzeFiles({kMainDart: lintWarningTrigger});
      expect(results.issues.length, 1);
      final issue = results.issues[0];
      expect(issue.line, 2);
      expect(issue.kind, 'info');
      expect(issue.message,
          'An uninitialized variable should have an explicit type annotation.');
    });

    test('files={} repro #126 - completions polluted on second request',
        () async {
      final files = <String, String>{kMainDart: completionFilterCode};
      final location = Location(kMainDart, 17);
      // https://github.com/dart-lang/dart-services/issues/126
      return analysisServer.completeFiles(files, location).then((results) {
        return analysisServer.completeFiles(files, location).then((results) {
          expect(results.replacementLength, 2);
          expect(results.replacementOffset, 16);
          expect(completionsContains(results, 'print'), true);
          expect(completionsContains(results, 'pow'), false);
        });
      });
    });

    test('files={} import_test', () async {
      // We're testing here that we don't have any path imports - we don't want
      // to enable browsing the file system.
      final testCode = "import '/'; main() { int a = 0; a. }";

      final results = await analysisServer
          .completeFiles({kMainDart: testCode}, Location(kMainDart, 9));
      final completions = results.completions;

      if (completions.isNotEmpty) {
        expect(completions.every((completion) {
          return completion.completion['completion']!.startsWith('dart:');
        }), true);
      }
    });

    test('files={} import_dart_core_test', () async {
      // Ensure we can import dart: imports.
      final testCode = "import 'dart:c'; main() { int a = 0; a. }";

      final results = await analysisServer
          .completeFiles({kMainDart: testCode}, Location(kMainDart, 14));
      final completions = results.completions;

      expect(
        completions.every((completion) =>
            completion.completion['completion']!.startsWith('dart:')),
        true,
      );
      expect(
        completions.any((completion) =>
            completion.completion['completion']!.startsWith('dart:')),
        true,
      );
    });

    test('files={} import_and_other_test', () async {
      final testCode = "import '/'; main() { int a = 0; a. }";

      final results = await analysisServer
          .completeFiles({kMainDart: testCode}, Location(kMainDart, 34));

      expect(completionsContains(results, 'abs'), true);
    });

    test('files={} myRandomName.dart + simple_quickFix', () async {
      final results = await analysisServer.getFixesMulti(
          {'myRandomName.dart': quickFixesCode},
          Location('myRandomName.dart', 25));

      expect(results.fixes.length, 2);

      // Fixes are not guaranteed to arrive in a particular order.
      results.fixes.sort((a, b) => a.offset.compareTo(b.offset));

      expect(results.fixes[0].offset, 20);
      expect(results.fixes[0].length, 1); // We need an insertion.

      expect(results.fixes[1].offset, 24);
      expect(results.fixes[1].length, 1); // We need an insertion.

      expect(results.fixes[1].fixes.length, 1);

      final candidateFix = results.fixes[1].fixes[0];

      expect(candidateFix.message.contains(';'), true);
      expect(candidateFix.edits[0].length, 0);
      expect(candidateFix.edits[0].offset, 25);
      expect(candidateFix.edits[0].replacement, ';');
    });

    test('files={} analyze', () async {
      final results =
          await analysisServer.analyzeFiles({kMainDart: sampleCode});
      expect(results.issues, isEmpty);
    });

    test('files={} analyze with errors', () async {
      final results =
          await analysisServer.analyzeFiles({kMainDart: sampleCodeError});
      expect(results.issues, hasLength(1));
    });

    test('files={} filter completions', () async {
      // just after A
      final idx = 61;
      expect(completionLargeNamespaces.substring(idx - 1, idx), 'A');
      final results = await analysisServer.completeFiles(
          {kMainDart: completionLargeNamespaces}, Location(kMainDart, 61));
      expect(completionsContains(results, 'A'), true);
      expect(completionsContains(results, 'AB'), true);
      expect(completionsContains(results, 'ABC'), true);
      expect(completionsContains(results, 'a'), true);
      expect(completionsContains(results, 'ZZ'), false);
    });
  });
}
