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

import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/resolver/scope.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
import 'package:analyzer/src/generated/testing/element_factory.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../src/dart/resolution/context_collection_resolution.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(ErrorResolverTest);
    defineReflectiveTests(PrefixedNamespaceTest);
    defineReflectiveTests(StrictModeTest);
    defineReflectiveTests(TypePropagationTest);
  });
}

@reflectiveTest
class ErrorResolverTest extends PubPackageResolutionTest {
  test_breakLabelOnSwitchMember() async {
    await assertErrorsInCode(r'''
class A {
  void m(int i) {
    switch (i) {
      l: case 0:
        break;
      case 1:
        break l;
    }
  }
}''', [
      error(CompileTimeErrorCode.BREAK_LABEL_ON_SWITCH_MEMBER, 105, 1),
    ]);
  }

  test_continueLabelOnSwitch() async {
    await assertErrorsInCode(r'''
class A {
  void m(int i) {
    l: switch (i) {
      case 0:
        continue l;
    }
  }
}''', [
      error(CompileTimeErrorCode.CONTINUE_LABEL_ON_SWITCH, 79, 1),
    ]);
  }

  test_enclosingElement_invalidLocalFunction() async {
    await assertErrorsInCode(r'''
class C {
  C() {
    int get x => 0;
  }
}''', [
      error(ParserErrorCode.EXPECTED_TOKEN, 26, 3),
      error(HintCode.UNUSED_LOCAL_VARIABLE, 26, 3),
      error(HintCode.UNUSED_ELEMENT, 30, 1),
      error(ParserErrorCode.MISSING_FUNCTION_PARAMETERS, 32, 2),
    ]);

    var constructor = findElement.unnamedConstructor('C');
    var x = findElement.localFunction('x');
    expect(x.enclosingElement, constructor);
  }
}

@reflectiveTest
class PrefixedNamespaceTest extends PubPackageResolutionTest {
  void test_lookup_missing() {
    ClassElement element = ElementFactory.classElement2('A');
    PrefixedNamespace namespace = PrefixedNamespace('p', _toMap([element]));
    expect(namespace.get('p.B'), isNull);
  }

  void test_lookup_missing_matchesPrefix() {
    ClassElement element = ElementFactory.classElement2('A');
    PrefixedNamespace namespace = PrefixedNamespace('p', _toMap([element]));
    expect(namespace.get('p'), isNull);
  }

  void test_lookup_valid() {
    ClassElement element = ElementFactory.classElement2('A');
    PrefixedNamespace namespace = PrefixedNamespace('p', _toMap([element]));
    expect(namespace.get('p.A'), same(element));
  }

  Map<String, Element> _toMap(List<Element> elements) {
    Map<String, Element> map = HashMap<String, Element>();
    for (Element element in elements) {
      map[element.name] = element;
    }
    return map;
  }
}

/// Instances of the class `StaticTypeVerifier` verify that all of the nodes in
/// an AST structure that should have a static type associated with them do have
/// a static type.
class StaticTypeVerifier extends GeneralizingAstVisitor<void> {
  /// A list containing all of the AST Expression nodes that were not resolved.
  final List<Expression> _unresolvedExpressions = <Expression>[];

  /// The TypeAnnotation nodes that were not resolved.
  final List<TypeAnnotation> _unresolvedTypes = <TypeAnnotation>[];

  /// Counter for the number of Expression nodes visited that are resolved.
  int _resolvedExpressionCount = 0;

  /// Counter for the number of TypeName nodes visited that are resolved.
  int _resolvedTypeCount = 0;

  /// Assert that all of the visited nodes have a static type associated with
  /// them.
  void assertResolved() {
    if (_unresolvedExpressions.isNotEmpty || _unresolvedTypes.isNotEmpty) {
      StringBuffer buffer = StringBuffer();
      int unresolvedTypeCount = _unresolvedTypes.length;
      if (unresolvedTypeCount > 0) {
        buffer.write("Failed to resolve ");
        buffer.write(unresolvedTypeCount);
        buffer.write(" of ");
        buffer.write(_resolvedTypeCount + unresolvedTypeCount);
        buffer.writeln(" type names:");
        for (TypeAnnotation identifier in _unresolvedTypes) {
          buffer.write("  ");
          buffer.write(identifier.toString());
          buffer.write(" (");
          buffer.write(_getFileName(identifier));
          buffer.write(" : ");
          buffer.write(identifier.offset);
          buffer.writeln(")");
        }
      }
      int unresolvedExpressionCount = _unresolvedExpressions.length;
      if (unresolvedExpressionCount > 0) {
        buffer.writeln("Failed to resolve ");
        buffer.write(unresolvedExpressionCount);
        buffer.write(" of ");
        buffer.write(_resolvedExpressionCount + unresolvedExpressionCount);
        buffer.writeln(" expressions:");
        for (Expression expression in _unresolvedExpressions) {
          buffer.write("  ");
          buffer.write(expression.toString());
          buffer.write(" (");
          buffer.write(_getFileName(expression));
          buffer.write(" : ");
          buffer.write(expression.offset);
          buffer.writeln(")");
        }
      }
      fail(buffer.toString());
    }
  }

  @override
  void visitBreakStatement(BreakStatement node) {}

  @override
  void visitCommentReference(CommentReference node) {}

  @override
  void visitContinueStatement(ContinueStatement node) {}

  @override
  void visitExportDirective(ExportDirective node) {}

  @override
  void visitExpression(Expression node) {
    node.visitChildren(this);
    DartType staticType = node.staticType;
    if (staticType == null) {
      _unresolvedExpressions.add(node);
    } else {
      _resolvedExpressionCount++;
    }
  }

  @override
  void visitImportDirective(ImportDirective node) {}

  @override
  void visitLabel(Label node) {}

  @override
  void visitLibraryIdentifier(LibraryIdentifier node) {}

  @override
  void visitPrefixedIdentifier(PrefixedIdentifier node) {
    // In cases where we have a prefixed identifier where the prefix is dynamic,
    // we don't want to assert that the node will have a type.
    if (node.staticType == null && node.prefix.staticType.isDynamic) {
      return;
    }
    super.visitPrefixedIdentifier(node);
  }

  @override
  void visitSimpleIdentifier(SimpleIdentifier node) {
    // In cases where identifiers are being used for something other than an
    // expressions, then they can be ignored.
    AstNode parent = node.parent;
    if (parent is MethodInvocation && identical(node, parent.methodName)) {
      return;
    } else if (parent is RedirectingConstructorInvocation &&
        identical(node, parent.constructorName)) {
      return;
    } else if (parent is SuperConstructorInvocation &&
        identical(node, parent.constructorName)) {
      return;
    } else if (parent is ConstructorName && identical(node, parent.name)) {
      return;
    } else if (parent is ConstructorFieldInitializer &&
        identical(node, parent.fieldName)) {
      return;
    } else if (node.staticElement is PrefixElement) {
      // Prefixes don't have a type.
      return;
    }
    super.visitSimpleIdentifier(node);
  }

  @override
  void visitTypeAnnotation(TypeAnnotation node) {
    if (node.type == null) {
      _unresolvedTypes.add(node);
    } else {
      _resolvedTypeCount++;
    }
    super.visitTypeAnnotation(node);
  }

  @override
  void visitTypeName(TypeName node) {
    // Note: do not visit children from this node, the child SimpleIdentifier in
    // TypeName (i.e. "String") does not have a static type defined.
    // TODO(brianwilkerson) Not visiting the children means that we won't catch
    // type arguments that were not resolved.
    if (node.type == null) {
      _unresolvedTypes.add(node);
    } else {
      _resolvedTypeCount++;
    }
  }

  String _getFileName(AstNode node) {
    // TODO (jwren) there are two copies of this method, one here and one in
    // ResolutionVerifier, they should be resolved into a single method
    if (node != null) {
      AstNode root = node.root;
      if (root is CompilationUnit) {
        CompilationUnit rootCU = root;
        if (rootCU.declaredElement != null) {
          return rootCU.declaredElement.source.fullName;
        } else {
          return "<unknown file- CompilationUnit.getElement() returned null>";
        }
      } else {
        return "<unknown file- CompilationUnit.getRoot() is not a CompilationUnit>";
      }
    }
    return "<unknown file- ASTNode is null>";
  }
}

/// The class `StrictModeTest` contains tests to ensure that the correct errors
/// and warnings are reported when the analysis engine is run in strict mode.
@reflectiveTest
class StrictModeTest extends PubPackageResolutionTest {
  test_assert_is() async {
    await assertErrorsInCode(r'''
int f(num n) {
  assert (n is int);
  return n & 0x0F;
}''', [
      error(CompileTimeErrorCode.UNDEFINED_OPERATOR, 47, 1),
    ]);
  }

  test_conditional_and_is() async {
    await assertNoErrorsInCode(r'''
int f(num n) {
  return (n is int && n > 0) ? n & 0x0F : 0;
}''');
  }

  test_conditional_is() async {
    await assertNoErrorsInCode(r'''
int f(num n) {
  return (n is int) ? n & 0x0F : 0;
}''');
  }

  test_conditional_isNot() async {
    await assertErrorsInCode(r'''
int f(num n) {
  return (n is! int) ? 0 : n & 0x0F;
}''', [
      error(CompileTimeErrorCode.UNDEFINED_OPERATOR, 44, 1),
    ]);
  }

  test_conditional_or_is() async {
    await assertErrorsInCode(r'''
int f(num n) {
  return (n is! int || n < 0) ? 0 : n & 0x0F;
}''', [
      error(CompileTimeErrorCode.UNDEFINED_OPERATOR, 53, 1),
    ]);
  }

  test_for() async {
    await assertErrorsInCode(r'''
int f(List<int> list) {
  num sum = 0;
  for (num i = 0; i < list.length; i++) {
    sum += list[i];
  }
}''', [
      error(HintCode.MISSING_RETURN, 4, 1),
      error(HintCode.UNUSED_LOCAL_VARIABLE, 30, 3),
    ]);
  }

  test_forEach() async {
    await assertErrorsInCode(r'''
int f(List<int> list) {
  num sum = 0;
  for (num n in list) {
    sum += n & 0x0F;
  }
}''', [
      error(HintCode.MISSING_RETURN, 4, 1),
      error(HintCode.UNUSED_LOCAL_VARIABLE, 30, 3),
      error(CompileTimeErrorCode.UNDEFINED_OPERATOR, 76, 1),
    ]);
  }

  test_if_and_is() async {
    await assertNoErrorsInCode(r'''
int f(num n) {
  if (n is int && n > 0) {
    return n & 0x0F;
  }
  return 0;
}''');
  }

  test_if_is() async {
    await assertNoErrorsInCode(r'''
int f(num n) {
  if (n is int) {
    return n & 0x0F;
  }
  return 0;
}''');
  }

  test_if_isNot() async {
    await assertErrorsInCode(r'''
int f(num n) {
  if (n is! int) {
    return 0;
  } else {
    return n & 0x0F;
  }
}''', [
      error(CompileTimeErrorCode.UNDEFINED_OPERATOR, 72, 1),
    ]);
  }

  test_if_isNot_abrupt() async {
    await assertErrorsInCode(r'''
int f(num n) {
  if (n is! int) {
    return 0;
  }
  return n & 0x0F;
}''', [
      error(CompileTimeErrorCode.UNDEFINED_OPERATOR, 63, 1),
    ]);
  }

  test_if_or_is() async {
    await assertErrorsInCode(r'''
int f(num n) {
  if (n is! int || n < 0) {
    return 0;
  } else {
    return n & 0x0F;
  }
}''', [
      error(CompileTimeErrorCode.UNDEFINED_OPERATOR, 81, 1),
    ]);
  }

  test_localVar() async {
    await assertErrorsInCode(r'''
int f() {
  num n = 1234;
  return n & 0x0F;
}''', [
      error(CompileTimeErrorCode.UNDEFINED_OPERATOR, 37, 1),
    ]);
  }
}

@reflectiveTest
class TypePropagationTest extends PubPackageResolutionTest {
  test_assignment_null() async {
    String code = r'''
main() {
  int v; // declare
  v = null;
  return v; // return
}''';
    await resolveTestCode(code);
    assertType(findElement.localVar('v').type, 'int');
    assertTypeNull(findNode.simple('v; // declare'));
    assertType(findNode.simple('v; // return'), 'int');
  }

  test_initializer_hasStaticType() async {
    await resolveTestCode(r'''
f() {
  int v = 0;
  return v;
}''');
    assertType(findElement.localVar('v').type, 'int');
    assertTypeNull(findNode.simple('v = 0;'));
    assertType(findNode.simple('v;'), 'int');
  }

  test_initializer_hasStaticType_parameterized() async {
    await resolveTestCode(r'''
f() {
  List<int> v = <int>[];
  return v;
}''');
    assertType(findElement.localVar('v').type, 'List<int>');
    assertTypeNull(findNode.simple('v ='));
    assertType(findNode.simple('v;'), 'List<int>');
  }

  test_initializer_null() async {
    await resolveTestCode(r'''
main() {
  int v = null;
  return v;
}''');
    assertType(findElement.localVar('v').type, 'int');
    assertTypeNull(findNode.simple('v ='));
    assertType(findNode.simple('v;'), 'int');
  }

  test_invocation_target_prefixed() async {
    newFile('$testPackageLibPath/a.dart', content: r'''
int max(int x, int y) => 0;
''');
    await resolveTestCode('''
import 'a.dart' as helper;
main() {
  helper.max(10, 10); // marker
}''');
    assertElement(
      findNode.simple('max(10, 10)'),
      findElement.importFind('package:test/a.dart').topFunction('max'),
    );
  }

  test_is_subclass() async {
    await resolveTestCode(r'''
class A {}
class B extends A {
  B m() => this;
}
A f(A p) {
  if (p is B) {
    return p.m();
  }
  return p;
}''');
    assertElement(
      findNode.methodInvocation('p.m()'),
      findElement.method('m', of: 'B'),
    );
  }

  test_mutatedOutsideScope() async {
    // https://code.google.com/p/dart/issues/detail?id=22732
    await assertNoErrorsInCode(r'''
class Base {
}

class Derived extends Base {
  get y => null;
}

class C {
  void f() {
    Base x = null;
    if (x is Derived) {
      print(x.y); // BAD
    }
    x = null;
  }
}

void g() {
  Base x = null;
  if (x is Derived) {
    print(x.y); // GOOD
  }
  x = null;
}''');
  }

  test_objectAccessInference_disabled_for_library_prefix() async {
    newFile('$testPackageLibPath/a.dart', content: '''
dynamic get hashCode => 42;
''');
    await assertNoErrorsInCode('''
import 'a.dart' as helper;
main() {
  helper.hashCode;
}''');
    assertTypeDynamic(findNode.prefixed('helper.hashCode'));
  }

  test_objectAccessInference_disabled_for_local_getter() async {
    await assertNoErrorsInCode('''
dynamic get hashCode => null;
main() {
  hashCode; // marker
}''');
    assertTypeDynamic(findNode.simple('hashCode; // marker'));
  }

  test_objectMethodInference_disabled_for_library_prefix() async {
    newFile('$testPackageLibPath/a.dart', content: '''
dynamic toString = (int x) => x + 42;
''');
    await assertNoErrorsInCode('''
import 'a.dart' as helper;
main() {
  helper.toString();
}''');
    assertTypeDynamic(
      findNode.functionExpressionInvocation('helper.toString()'),
    );
  }

  test_objectMethodInference_disabled_for_local_function() async {
    await resolveTestCode('''
main() {
  dynamic toString = () => null;
  toString(); // marker
}''');
    assertTypeDynamic(findElement.localVar('toString').type);
    assertTypeNull(findNode.simple('toString ='));
    assertTypeDynamic(findNode.simple('toString(); // marker'));
  }

  @failingTest
  test_propagatedReturnType_functionExpression() async {
    // TODO(scheglov) disabled because we don't resolve function expression
    await resolveTestCode(r'''
main() {
  var v = (() {return 42;})();
}''');
    assertTypeDynamic(findNode.simple('v = '));
  }
}
