// 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/error/error.dart';
import 'package:analyzer/src/dart/analysis/driver.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_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('/project/existing_part1.dart', 'part of lib;');
    addSource('/project/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';
import 'b.dart';
import 'c.dart';
// c
// aa
// bbb

/** 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);
    AnalysisResult result = await driver.getResult(testSource.fullName);
    testUnit = result.unit;
    testErrors = result.errors;
  }
}
