// 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 'dart:async';

import 'package:analysis_server/src/services/correction/organize_directives.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart'
    hide AnalysisError;
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../../abstract_single_unit.dart';

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

@reflectiveTest
class OrganizeDirectivesTest extends AbstractSingleUnitTest {
  List<AnalysisError> testErrors;

  test_docComment_beforeDirective_hasUnresolvedIdentifier() async {
    await _computeUnitAndErrors(r'''
/// Library documentation comment A
/// Library documentation comment B
import 'a.dart';
import 'b.dart';

B b;
''');
    // validate change
    _assertOrganize(r'''
/// Library documentation comment A
/// Library documentation comment B
import 'a.dart';
import 'b.dart';

B b;
''');
  }

  test_keep_duplicateImports_withDifferentPrefix() async {
    await _computeUnitAndErrors(r'''
import 'dart:async' as async1;
import 'dart:async' as async2;

main() {
  async1.Future f;
  async2.Stream s;
}''');
    // validate change
    _assertOrganize(r'''
import 'dart:async' as async1;
import 'dart:async' as async2;

main() {
  async1.Future f;
  async2.Stream s;
}''', removeUnresolved: true, removeUnused: true);
  }

  test_remove_duplicateImports() async {
    await _computeUnitAndErrors(r'''
import 'dart:async';
import 'dart:async';

main() {
  Future f;
}''');
    // validate change
    _assertOrganize(r'''
import 'dart:async';

main() {
  Future f;
}''', removeUnresolved: true, removeUnused: true);
  }

  test_remove_duplicateImports_differentText_uri() async {
    await _computeUnitAndErrors(r'''
import 'dart:async' as async;
import "dart:async" as async;

main() {
  async.Future f;
}''');
    // validate change
    _assertOrganize(r'''
import 'dart:async' as async;

main() {
  async.Future f;
}''', removeUnresolved: true, removeUnused: true);
  }

  test_remove_duplicateImports_withSamePrefix() async {
    await _computeUnitAndErrors(r'''
import 'dart:async' as async;
import 'dart:async' as async;

main() {
  async.Future f;
}''');
    // validate change
    _assertOrganize(r'''
import 'dart:async' as async;

main() {
  async.Future f;
}''', removeUnresolved: true, removeUnused: true);
  }

  test_remove_unresolvedDirectives() async {
    addSource('/home/test/lib/existing_part1.dart', 'part of lib;');
    addSource('/home/test/lib/existing_part2.dart', 'part of lib;');
    await _computeUnitAndErrors(r'''
library lib;

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

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

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

main() {
}
''');
    // validate change
    _assertOrganize(r'''
library lib;

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

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

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

main() {
}
''', removeUnresolved: true);
  }

  test_remove_unusedImports() async {
    await _computeUnitAndErrors(r'''
library lib;

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

main() {
  print(PI);
  new HashMap();
}
''');
    // validate change
    _assertOrganize(r'''
library lib;

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

main() {
  print(PI);
  new HashMap();
}
''', removeUnused: true);
  }

  test_remove_unusedImports2() async {
    await _computeUnitAndErrors(r'''
import 'dart:async';
import 'dart:math';

class A {}

main() {
  Future f;
}''');
    // validate change
    _assertOrganize(r'''
import 'dart:async';

class A {}

main() {
  Future f;
}''', removeUnresolved: true, removeUnused: true);
  }

  test_remove_unusedImports_hasUnresolvedError() async {
    Future<void> check(String declaration) async {
      String code = '''
import 'dart:async';
$declaration
''';
      await _computeUnitAndErrors(code);
      _assertOrganize(code, removeUnused: true);
    }

    await check('main() { Unresolved v; }');
    await check('main() { new Unresolved(); }');
    await check('main() { const Unresolved(); }');
    await check('main() { unresolvedFunction(); }');
    await check('main() { print(unresolvedVariable); }');
    await check('main() { unresolvedVariable = 0; }');
    await check('main() { Unresolved.field = 0; }');
    await check('class A extends Unresolved {}');
    await check('List<Unresolved> v;');
  }

  test_sort() async {
    await _computeUnitAndErrors(r'''
library lib;

export 'dart:bbb';
import 'dart:bbb';
export 'package:bbb/bbb.dart';
export 'http://bbb.com';
import 'bbb/bbb.dart';
export 'http://aaa.com';
import 'http://bbb.com';
export 'dart:aaa';
export 'package:aaa/aaa.dart';
import 'package:bbb/bbb.dart';
export 'aaa/aaa.dart';
export 'bbb/bbb.dart';
import 'dart:aaa';
import 'package:aaa/aaa.dart';
import 'aaa/aaa.dart';
import 'http://aaa.com';
part 'bbb/bbb.dart';
part 'aaa/aaa.dart';

main() {
}
''');
    // validate change
    _assertOrganize(r'''
library lib;

import 'dart:aaa';
import 'dart:bbb';

import 'package:aaa/aaa.dart';
import 'package:bbb/bbb.dart';

import 'http://aaa.com';
import 'http://bbb.com';

import 'aaa/aaa.dart';
import 'bbb/bbb.dart';

export 'dart:aaa';
export 'dart:bbb';

export 'package:aaa/aaa.dart';
export 'package:bbb/bbb.dart';

export 'http://aaa.com';
export 'http://bbb.com';

export 'aaa/aaa.dart';
export 'bbb/bbb.dart';

part 'aaa/aaa.dart';
part 'bbb/bbb.dart';

main() {
}
''');
  }

  test_sort_hasComments() async {
    await _computeUnitAndErrors(r'''
// header
library lib;

import 'c.dart';// c
import 'a.dart';// aa
import 'b.dart';// bbb

/** doc */
main() {
}
''');
    // validate change
    _assertOrganize(r'''
// header
library lib;

import 'a.dart';// aa
import 'b.dart';// bbb
import 'c.dart';// c

/** doc */
main() {
}
''');
  }

  test_sort_imports_packageAndPath() async {
    await _computeUnitAndErrors(r'''
library lib;

import 'package:product.ui.api.bbb/manager1.dart';
import 'package:product.ui.api/entity2.dart';
import 'package:product.ui/entity.dart';
import 'package:product.ui.api.aaa/manager2.dart';
import 'package:product.ui.api/entity1.dart';
import 'package:product2.client/entity.dart';
''');
    // validate change
    _assertOrganize(r'''
library lib;

import 'package:product.ui/entity.dart';
import 'package:product.ui.api/entity1.dart';
import 'package:product.ui.api/entity2.dart';
import 'package:product.ui.api.aaa/manager2.dart';
import 'package:product.ui.api.bbb/manager1.dart';
import 'package:product2.client/entity.dart';
''');
  }

  void _assertOrganize(String expectedCode,
      {bool removeUnresolved = false, bool removeUnused = false}) {
    DirectiveOrganizer organizer = new DirectiveOrganizer(
        testCode, testUnit, testErrors,
        removeUnresolved: removeUnresolved, removeUnused: removeUnused);
    List<SourceEdit> edits = organizer.organize();
    String result = SourceEdit.applySequence(testCode, edits);
    expect(result, expectedCode);
  }

  Future<void> _computeUnitAndErrors(String code) async {
    addTestSource(code);
    ResolvedUnitResult result =
        await session.getResolvedUnit(testSource.fullName);
    testUnit = result.unit;
    testErrors = result.errors;
  }
}
