// 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.

library test.edit.organize_directives;

import 'dart:async';

import 'package:analysis_server/src/edit/edit_domain.dart';
import 'package:analysis_server/src/protocol.dart';
import 'package:plugin/manager.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:unittest/unittest.dart' hide ERROR;

import '../analysis_abstract.dart';
import '../mocks.dart';
import '../utils.dart';

main() {
  initializeTestEnvironment();
  defineReflectiveTests(OrganizeDirectivesTest);
}

@reflectiveTest
class OrganizeDirectivesTest extends AbstractAnalysisTest {
  SourceFileEdit fileEdit;

  @override
  void setUp() {
    super.setUp();
    createProject();
    ExtensionManager manager = new ExtensionManager();
    manager.processPlugins([server.serverPlugin]);
    handler = new EditDomainHandler(server);
  }

  Future test_BAD_doesNotExist() async {
    await waitForTasksFinished();
    Request request =
        new EditOrganizeDirectivesParams('/no/such/file.dart').toRequest('0');
    Response response = handler.handleRequest(request);
    expect(
        response, isResponseFailure('0', RequestErrorCode.FILE_NOT_ANALYZED));
  }

  Future test_BAD_hasParseError() async {
    addTestFile('''
import 'dart:async'

main() {}
''');
    await waitForTasksFinished();
    Request request = new EditOrganizeDirectivesParams(testFile).toRequest('0');
    Response response = handler.handleRequest(request);
    expect(response,
        isResponseFailure('0', RequestErrorCode.ORGANIZE_DIRECTIVES_ERROR));
  }

  Future test_BAD_notDartFile() async {
    await waitForTasksFinished();
    Request request =
        new EditOrganizeDirectivesParams('/not-a-Dart-file.txt').toRequest('0');
    Response response = handler.handleRequest(request);
    expect(
        response, isResponseFailure('0', RequestErrorCode.FILE_NOT_ANALYZED));
  }

  Future test_OK_remove_unresolvedDirectives() {
    addFile('$testFolder/existing_part1.dart', 'part of lib;');
    addFile('$testFolder/existing_part2.dart', 'part of lib;');
    addTestFile('''
library lib;

export 'dart:noSuchExportSdkLibrary';
export 'dart:async';
export 'package:noSuchExportPackage/andLib.dart';
export 'dart:math';

import 'dart:async';
import 'dart:noSuchImportSdkLibrary';
import 'dart:math';
import 'package:noSuchImportPackage/andLib.dart';

part 'existing_part1.dart';
part 'no_such_part.dart';
part 'existing_part2.dart';

main(Future f) {
  print(PI);
}
''');
    return _assertOrganized(r'''
library lib;

import 'dart:async';
import 'dart:math';

export 'dart:async';
export 'dart:math';

part 'existing_part1.dart';
part 'existing_part2.dart';

main(Future f) {
  print(PI);
}
''');
  }

  Future test_OK_remove_unusedImports() {
    addTestFile('''
library lib;

import 'dart:async';
import 'dart:math';
import 'dart:convert';
import 'dart:collection';

main() {
  print(PI);
  new HashMap();
}
''');
    return _assertOrganized(r'''
library lib;

import 'dart:collection';
import 'dart:math';

main() {
  print(PI);
  new HashMap();
}
''');
  }

  Future _assertOrganized(String expectedCode) async {
    await waitForTasksFinished();
    _requestOrganize();
    String resultCode = SourceEdit.applySequence(testCode, fileEdit.edits);
    expect(resultCode, expectedCode);
  }

  void _requestOrganize() {
    Request request = new EditOrganizeDirectivesParams(testFile).toRequest('0');
    Response response = handleSuccessfulRequest(request);
    var result = new EditOrganizeDirectivesResult.fromResponse(response);
    fileEdit = result.edit;
  }
}
