// 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 'package:analysis_server/protocol/protocol.dart';
import 'package:analysis_server/protocol/protocol_constants.dart';
import 'package:analysis_server/protocol/protocol_generated.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/utilities/package_config_file_builder.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../analysis_server_base.dart';
import '../mocks.dart';

void main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(UpdateContentTest);
  });
}

@reflectiveTest
class UpdateContentTest extends PubPackageAnalysisServerTest {
  Map<File, List<String>> filesErrors = {};
  int serverErrorCount = 0;
  int navigationCount = 0;

  @override
  void processNotification(Notification notification) {
    if (notification.event == ANALYSIS_NOTIFICATION_ERRORS) {
      var decoded = AnalysisErrorsParams.fromNotification(
        notification,
        clientUriConverter: server.uriConverter,
      );
      String format(AnalysisError e) => '${e.location.startLine}: ${e.message}';
      filesErrors[getFile(decoded.file)] = decoded.errors.map(format).toList();
    }
    if (notification.event == ANALYSIS_NOTIFICATION_NAVIGATION) {
      navigationCount++;
    }
    if (notification.event == SERVER_NOTIFICATION_ERROR) {
      serverErrorCount++;
    }
  }

  void test_illegal_ChangeContentOverlay() async {
    // It should be illegal to send a ChangeContentOverlay for a file that
    // doesn't have an overlay yet.
    addTestFile('');
    await setRoots(included: [workspaceRootPath], excluded: []);
    var response = await handleRequest(
      AnalysisUpdateContentParams({
        testFile.path: ChangeContentOverlay([SourceEdit(0, 0, '')]),
      }).toRequest('0', clientUriConverter: server.uriConverter),
    );
    assertResponseFailure(
      response,
      requestId: '0',
      errorCode: RequestErrorCode.INVALID_OVERLAY_CHANGE,
    );
  }

  Future<void> test_invalidFilePathFormat_notAbsolute() async {
    var response = await handleRequest(
      AnalysisUpdateContentParams({
        'test.dart': AddContentOverlay(''),
      }).toRequest('0', clientUriConverter: server.uriConverter),
    );
    expect(
      response,
      isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT),
    );
  }

  Future<void> test_invalidFilePathFormat_notNormalized() async {
    var response = await handleRequest(
      AnalysisUpdateContentParams({
        convertPath('/foo/../bar/test.dart'): AddContentOverlay(''),
      }).toRequest('0', clientUriConverter: server.uriConverter),
    );
    expect(
      response,
      isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT),
    );
  }

  Future<void> test_multiple_contexts() async {
    writePackageConfig(
      workspaceRootPath,
      config:
          PackageConfigFileBuilder()
            ..add(name: 'aaa', rootPath: '$workspaceRootPath/aaa'),
    );

    var aaa = newFile('$workspaceRootPath/aaa/lib/aaa.dart', r'''
void f(int _) {}
''');

    var foo = newFile('$workspaceRootPath/foo/lib/foo.dart', r'''
import 'package:aaa/aaa.dart';
void g() {
  f();
}
''');

    var bar = newFile('$workspaceRootPath/bar/lib/bar.dart', r'''
import 'package:aaa/aaa.dart';
void g() {
  f();
}
''');

    await setRoots(included: [foo.parent.path, bar.parent.path], excluded: []);

    {
      await waitForTasksFinished();
      // Files foo.dart and bar.dart should both have errors, since they both
      // call f() with the wrong number of arguments.
      expect(filesErrors[foo], hasLength(1));
      expect(filesErrors[bar], hasLength(1));
      // Overlay the content of baz.dart to eliminate the errors.
      await handleSuccessfulRequest(
        AnalysisUpdateContentParams({
          aaa.path: AddContentOverlay('void f() {}'),
        }).toRequest('0', clientUriConverter: server.uriConverter),
      );
    }

    {
      await waitForTasksFinished();
      // The overlay should have been propagated to both contexts, causing both
      // foo.dart and bar.dart to be reanalyzed and found to be free of errors.
      expect(filesErrors[foo], isEmpty);
      expect(filesErrors[bar], isEmpty);
    }
  }

  @failingTest
  Future<void> test_overlay_addPreviouslyImported() async {
    // The list of errors doesn't include errors for '/project/target.dart'.
    var project = newFolder('/project');
    await setRoots(included: [project.path], excluded: []);

    await handleSuccessfulRequest(
      AnalysisUpdateContentParams({
        '/project/main.dart': AddContentOverlay('import "target.dart";'),
      }).toRequest('0', clientUriConverter: server.uriConverter),
    );
    await waitForTasksFinished();
    expect(filesErrors, {
      '/project/main.dart': ["1: Target of URI doesn't exist: 'target.dart'."],
      '/project/target.dart': [],
    });

    await handleSuccessfulRequest(
      AnalysisUpdateContentParams({
        '/project/target.dart': AddContentOverlay('import "none.dart";'),
      }).toRequest('0', clientUriConverter: server.uriConverter),
    );
    await waitForTasksFinished();
    expect(filesErrors, {
      '/project/main.dart': ['1: Unused import.'],
      '/project/target.dart': ["1: Target of URI doesn't exist: 'none.dart'."],
      '/project/none.dart': [],
    });
  }

  Future<void> test_overlayOnly() async {
    var a = newFile('$testPackageLibPath/a.dart', '');
    var b = getFile('$testPackageLibPath/b.dart');

    await setRoots(included: [workspaceRootPath], excluded: []);
    await waitForTasksFinished();
    expect(filesErrors[a], isEmpty);
    expect(filesErrors[b], isNull);

    // Add `b.dart` overlay, analyzed.
    await handleSuccessfulRequest(
      AnalysisUpdateContentParams({
        b.path: AddContentOverlay(''),
      }).toRequest('0', clientUriConverter: server.uriConverter),
    );
    await waitForTasksFinished();
    expect(filesErrors[a], isEmpty);
    expect(filesErrors[b], isEmpty);

    // Add `b.dart` overlay, analyzed.
    await handleSuccessfulRequest(
      AnalysisUpdateContentParams({
        b.path: RemoveContentOverlay(),
      }).toRequest('0', clientUriConverter: server.uriConverter),
    );
    await waitForTasksFinished();
    expect(filesErrors[a], isEmpty);
    // TODO(scheglov): We should get "flush" notification.
    // expect(filesErrors[b], isNull);
  }

  @failingTest
  Future<void> test_sendNoticesAfterNopChange() async {
    // The errors are empty on the last line.
    addTestFile('');
    await setRoots(included: [workspaceRootPath], excluded: []);
    await waitForTasksFinished();
    // add an overlay
    await handleSuccessfulRequest(
      AnalysisUpdateContentParams({
        testFile.path: AddContentOverlay('void f() {} void f() {}'),
      }).toRequest('0', clientUriConverter: server.uriConverter),
    );
    await waitForTasksFinished();
    // clear errors and make a no-op change
    filesErrors.clear();
    await handleSuccessfulRequest(
      AnalysisUpdateContentParams({
        testFile.path: ChangeContentOverlay([SourceEdit(5, 1, 'f')]),
      }).toRequest('0', clientUriConverter: server.uriConverter),
    );
    await waitForTasksFinished();
    // errors should have been resent
    expect(filesErrors, isNotEmpty);
  }

  @failingTest
  Future<void> test_sendNoticesAfterNopChange_flushedUnit() async {
    // The list of errors is empty on the last line.
    addTestFile('');
    await setRoots(included: [workspaceRootPath], excluded: []);
    await waitForTasksFinished();
    // add an overlay
    await handleSuccessfulRequest(
      AnalysisUpdateContentParams({
        testFile.path: AddContentOverlay('void f() {} void f() {}'),
      }).toRequest('0', clientUriConverter: server.uriConverter),
    );
    await waitForTasksFinished();
    // clear errors and make a no-op change
    filesErrors.clear();
    await handleSuccessfulRequest(
      AnalysisUpdateContentParams({
        testFile.path: ChangeContentOverlay([SourceEdit(5, 1, 'f')]),
      }).toRequest('0', clientUriConverter: server.uriConverter),
    );
    await waitForTasksFinished();
    // errors should have been resent
    expect(filesErrors, isNotEmpty);
  }

  Future<void> test_sentToPlugins() async {
    var filePath = convertPath('$testPackageLibPath/a.dart');
    var fileContent = 'import "none.dart";';
    //
    // Add
    //
    await handleSuccessfulRequest(
      AnalysisUpdateContentParams(<String, Object>{
        filePath: AddContentOverlay(fileContent),
      }).toRequest('0', clientUriConverter: server.uriConverter),
    );
    var params = pluginManager.analysisUpdateContentParams!;
    var files = params.files;
    expect(files, hasLength(1));
    var overlay = files[filePath];
    expect(overlay, const TypeMatcher<AddContentOverlay>());
    var addOverlay = overlay as AddContentOverlay;
    expect(addOverlay.content, fileContent);
    //
    // Change
    //
    pluginManager.analysisUpdateContentParams = null;
    await handleSuccessfulRequest(
      AnalysisUpdateContentParams(<String, Object>{
        filePath: ChangeContentOverlay(<SourceEdit>[
          SourceEdit(8, 1, "'"),
          SourceEdit(18, 1, "'"),
        ]),
      }).toRequest('1', clientUriConverter: server.uriConverter),
    );
    params = pluginManager.analysisUpdateContentParams!;
    expect(params, isNotNull);
    files = params.files;
    expect(files, hasLength(1));
    overlay = files[filePath];
    expect(overlay, const TypeMatcher<ChangeContentOverlay>());
    var changeOverlay = overlay as ChangeContentOverlay;
    expect(changeOverlay.edits, hasLength(2));
    //
    // Remove
    //
    pluginManager.analysisUpdateContentParams = null;
    await handleSuccessfulRequest(
      AnalysisUpdateContentParams(<String, Object>{
        filePath: RemoveContentOverlay(),
      }).toRequest('2', clientUriConverter: server.uriConverter),
    );
    params = pluginManager.analysisUpdateContentParams!;
    expect(params, isNotNull);
    files = params.files;
    expect(files, hasLength(1));
    overlay = files[filePath];
    expect(overlay, const TypeMatcher<RemoveContentOverlay>());
  }
}
