// Copyright (c) 2014, 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_generated.dart';
import 'package:analysis_server/src/domain_analysis.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_abstract.dart';
import '../mocks.dart';

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

@reflectiveTest
class GetErrorsTest extends AbstractAnalysisTest {
  static const String requestId = 'test-getError';

  @override
  Future<void> setUp() async {
    super.setUp();
    server.handlers = [
      AnalysisDomainHandler(server),
    ];
    await createProject();
  }

  Future<void> test_afterAnalysisComplete() async {
    addTestFile('''
main() {
  print(42)
}
''');
    await waitForTasksFinished();
    var errors = await _getErrors(testFile);
    expect(errors, hasLength(1));
  }

  Future<void> test_errorInPart() async {
    var libPath = join(testFolder, 'main.dart');
    var partPath = join(testFolder, 'main_part.dart');
    newFile(libPath, content: r'''
library main;
part 'main_part.dart';
class A {}
''');
    newFile(partPath, content: r'''
part of main;
class A {}
''');
    await waitForTasksFinished();
    {
      var libErrors = await _getErrors(libPath);
      expect(libErrors, isEmpty);
    }
    {
      var partErrors = await _getErrors(partPath);
      expect(partErrors, hasLength(1));
    }
  }

  @failingTest
  Future<void> test_fileWithoutContext() async {
    // Broken under the new driver.
    var file = convertPath('/outside.dart');
    newFile(file, content: '''
main() {
  print(42);
}
''');
    await _checkInvalid(file);
  }

  Future<void> test_hasErrors() async {
    addTestFile('''
main() {
  print(42)
}
''');
    var errors = await _getErrors(testFile);
    expect(errors, hasLength(1));
    {
      var error = errors[0];
      expect(error.severity, AnalysisErrorSeverity.ERROR);
      expect(error.type, AnalysisErrorType.SYNTACTIC_ERROR);
      expect(error.location.file, testFile);
      expect(error.location.startLine, 2);
    }
  }

  Future<void> test_invalidFilePathFormat_notAbsolute() async {
    var request = _createGetErrorsRequest('test.dart');
    var response = await waitResponse(request);
    expect(
      response,
      isResponseFailure(requestId, RequestErrorCode.INVALID_FILE_PATH_FORMAT),
    );
  }

  Future<void> test_invalidFilePathFormat_notNormalized() async {
    var request = _createGetErrorsRequest(convertPath('/foo/../bar/test.dart'));
    var response = await waitResponse(request);
    expect(
      response,
      isResponseFailure(requestId, RequestErrorCode.INVALID_FILE_PATH_FORMAT),
    );
  }

  Future<void> test_noErrors() async {
    addTestFile('''
main() {
  print(42);
}
''');
    var errors = await _getErrors(testFile);
    expect(errors, isEmpty);
  }

  Future<void> _checkInvalid(String file) async {
    var request = _createGetErrorsRequest(file);
    var response = await serverChannel.sendRequest(request);
    expect(response.error, isNotNull);
    expect(response.error!.code, RequestErrorCode.GET_ERRORS_INVALID_FILE);
  }

  Request _createGetErrorsRequest(String file) {
    return AnalysisGetErrorsParams(file).toRequest(requestId);
  }

  Future<List<AnalysisError>> _getErrors(String file) async {
    var request = _createGetErrorsRequest(file);
    var response = await serverChannel.sendRequest(request);
    return AnalysisGetErrorsResult.fromResponse(response).errors;
  }
}
