// 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_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';
import '../services/refactoring/abstract_rename.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);
      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'),
    );
    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'),
    );
    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'),
    );
    expect(
      response,
      isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT),
    );
  }

  Future<void> test_multiple_contexts() async {
    writePackageConfig(
      getFolder(workspaceRootPath),
      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'),
      );
    }

    {
      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'),
    );
    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'),
    );
    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'),
    );
    await waitForTasksFinished();
    expect(filesErrors[a], isEmpty);
    expect(filesErrors[b], isEmpty);

    // Add `b.dart` overlay, analyzed.
    await handleSuccessfulRequest(
      AnalysisUpdateContentParams({
        b.path: RemoveContentOverlay(),
      }).toRequest('0'),
    );
    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'),
    );
    await waitForTasksFinished();
    // clear errors and make a no-op change
    filesErrors.clear();
    await handleSuccessfulRequest(
      AnalysisUpdateContentParams({
        testFile.path: ChangeContentOverlay([
          SourceEdit(5, 1, 'f'),
        ]),
      }).toRequest('0'),
    );
    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'),
    );
    await waitForTasksFinished();
    // clear errors and make a no-op change
    filesErrors.clear();
    await handleSuccessfulRequest(
      AnalysisUpdateContentParams({
        testFile.path: ChangeContentOverlay([
          SourceEdit(5, 1, 'f'),
        ]),
      }).toRequest('0'),
    );
    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'),
    );
    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'),
    );
    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'),
    );
    params = pluginManager.analysisUpdateContentParams!;
    expect(params, isNotNull);
    files = params.files;
    expect(files, hasLength(1));
    overlay = files[filePath];
    expect(overlay, const TypeMatcher<RemoveContentOverlay>());
  }
}
