// Copyright (c) 2017, 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/src/utilities/flutter.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

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

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

@reflectiveTest
class FlutterTest extends AbstractSingleUnitTest {
  @override
  // TODO(brianwilkerson) Update these tests. I believe that will require
  //  updating the mock flutter package.
  String? get testPackageLanguageVersion => '2.9';

  Flutter get _flutter => Flutter.instance;

  @override
  void setUp() {
    super.setUp();
    writeTestPackageConfig(
      flutter: true,
    );
  }

  Future<void> test_getWidgetPresentationText_icon() async {
    await resolveTestCode('''
import 'package:flutter/material.dart';
var w = const Icon(Icons.book);
''');
    var w = _getTopVariableCreation('w');
    expect(_flutter.getWidgetPresentationText(w), 'Icon(Icons.book)');
  }

  Future<void> test_getWidgetPresentationText_icon_withoutArguments() async {
    verifyNoTestUnitErrors = false;
    await resolveTestCode('''
import 'package:flutter/material.dart';
var w = const Icon();
''');
    var w = _getTopVariableCreation('w');
    expect(_flutter.getWidgetPresentationText(w), 'Icon');
  }

  Future<void> test_getWidgetPresentationText_notWidget() async {
    await resolveTestCode('''
import 'package:flutter/material.dart';
var w = new Object();
''');
    var w = _getTopVariableCreation('w');
    expect(_flutter.getWidgetPresentationText(w), isNull);
  }

  Future<void> test_getWidgetPresentationText_text() async {
    await resolveTestCode('''
import 'package:flutter/material.dart';
var w = const Text('foo');
''');
    var w = _getTopVariableCreation('w');
    expect(_flutter.getWidgetPresentationText(w), "Text('foo')");
  }

  Future<void> test_getWidgetPresentationText_text_longText() async {
    await resolveTestCode('''
import 'package:flutter/material.dart';
var w = const Text('${'abc' * 100}');
''');
    var w = _getTopVariableCreation('w');
    expect(
      _flutter.getWidgetPresentationText(w),
      "Text('abcabcabcabcab...cabcabcabcabc')",
    );
  }

  Future<void> test_getWidgetPresentationText_text_withoutArguments() async {
    verifyNoTestUnitErrors = false;
    await resolveTestCode('''
import 'package:flutter/material.dart';
var w = const Text();
''');
    var w = _getTopVariableCreation('w');
    expect(_flutter.getWidgetPresentationText(w), 'Text');
  }

  Future<void> test_getWidgetPresentationText_unresolved() async {
    verifyNoTestUnitErrors = false;
    await resolveTestCode('''
import 'package:flutter/material.dart';
var w = new Foo();
''');
    var w = _getTopVariableCreation('w');
    expect(_flutter.getWidgetPresentationText(w), isNull);
  }

  Future<void> test_identifyWidgetExpression_node_instanceCreation() async {
    await resolveTestCode('''
import 'package:flutter/widgets.dart';

void f() {
  new MyWidget(1234);
  new MyWidget.named(5678);
}

class MyWidget extends StatelessWidget {
  MyWidget(int a);
  MyWidget.named(int a);
  Widget build(BuildContext context) => null;
}
''');
    var f = testUnit.declarations[0] as FunctionDeclaration;
    var body = f.functionExpression.body as BlockFunctionBody;
    var statements = body.block.statements;

    // new MyWidget(1234);
    {
      var statement = statements[0] as ExpressionStatement;
      var creation = statement.expression as InstanceCreationExpression;
      var constructorName = creation.constructorName;
      var namedType = constructorName.type;
      var argumentList = creation.argumentList;
      expect(_flutter.identifyWidgetExpression(creation), creation);
      expect(_flutter.identifyWidgetExpression(constructorName), creation);
      expect(_flutter.identifyWidgetExpression(namedType), creation);
      expect(_flutter.identifyWidgetExpression(argumentList), isNull);
      expect(
        _flutter.identifyWidgetExpression(argumentList.arguments[0]),
        isNull,
      );
    }

    // new MyWidget.named(5678);
    {
      var statement = statements[1] as ExpressionStatement;
      var creation = statement.expression as InstanceCreationExpression;
      var constructorName = creation.constructorName;
      var namedType = constructorName.type;
      var argumentList = creation.argumentList;
      expect(_flutter.identifyWidgetExpression(creation), creation);
      expect(_flutter.identifyWidgetExpression(constructorName), creation);
      expect(_flutter.identifyWidgetExpression(namedType), creation);
      expect(_flutter.identifyWidgetExpression(namedType.name), creation);
      expect(_flutter.identifyWidgetExpression(constructorName.name), creation);
      expect(_flutter.identifyWidgetExpression(argumentList), isNull);
      expect(
        _flutter.identifyWidgetExpression(argumentList.arguments[0]),
        isNull,
      );
    }
  }

  Future<void> test_identifyWidgetExpression_node_invocation() async {
    await resolveTestCode('''
import 'package:flutter/widgets.dart';

void f() {
  createEmptyText();
  createText('xyz');
}

Text createEmptyText() => new Text('');
Text createText(String txt) => new Text(txt);
''');
    {
      var invocation = findNode.methodInvocation('createEmptyText();');
      expect(_flutter.identifyWidgetExpression(invocation), invocation);
      var argumentList = invocation.argumentList;
      expect(_flutter.identifyWidgetExpression(argumentList), isNull);
    }

    {
      var invocation = findNode.methodInvocation("createText('xyz');");
      expect(_flutter.identifyWidgetExpression(invocation), invocation);
      var argumentList = invocation.argumentList;
      expect(_flutter.identifyWidgetExpression(argumentList), isNull);
      expect(
        _flutter.identifyWidgetExpression(argumentList.arguments[0]),
        isNull,
      );
    }
  }

  Future<void> test_identifyWidgetExpression_node_namedExpression() async {
    await resolveTestCode('''
import 'package:flutter/widgets.dart';

void f() {
  new Container(child: new Text(''));
}

Text createEmptyText() => new Text('');
''');
    var childExpression = findNode.namedExpression('child: ');
    expect(_flutter.identifyWidgetExpression(childExpression), isNull);
  }

  Future<void>
      test_identifyWidgetExpression_node_prefixedIdentifier_identifier() async {
    await resolveTestCode('''
import 'package:flutter/widgets.dart';

abstract class Foo extends Widget {
  Widget bar;
}

void f(Foo foo) {
  foo.bar; // ref
}
''');
    var bar = findNode.simple('bar; // ref');
    expect(_flutter.identifyWidgetExpression(bar), bar.parent);
  }

  Future<void>
      test_identifyWidgetExpression_node_prefixedIdentifier_prefix() async {
    await resolveTestCode('''
import 'package:flutter/widgets.dart';

abstract class Foo extends Widget {
  Widget bar;
}

void f(Foo foo) {
  foo.bar; // ref
}
''');
    var foo = findNode.simple('foo.bar');
    expect(_flutter.identifyWidgetExpression(foo), foo.parent);
  }

  Future<void> test_identifyWidgetExpression_node_simpleIdentifier() async {
    await resolveTestCode('''
import 'package:flutter/widgets.dart';

void f(Widget widget) {
  widget; // ref
}
''');
    var expression = findNode.simple('widget; // ref');
    expect(_flutter.identifyWidgetExpression(expression), expression);
  }

  Future<void> test_identifyWidgetExpression_null() async {
    await resolveTestCode('''
import 'package:flutter/widgets.dart';

void f() {
  var intVariable = 42;
  intVariable;
}

Text createEmptyText() => new Text('');
''');
    expect(_flutter.identifyWidgetExpression(null), isNull);
    {
      var expression = findNode.integerLiteral('42;');
      expect(_flutter.identifyWidgetExpression(expression), isNull);
    }

    {
      var expression = findNode.simple('intVariable;');
      expect(_flutter.identifyWidgetExpression(expression), isNull);
    }
  }

  Future<void> test_identifyWidgetExpression_parent_argumentList() async {
    await resolveTestCode('''
import 'package:flutter/widgets.dart';

void f() {
  var text = new Text('abc');
  useWidget(text); // ref
}

void useWidget(Widget w) {}
''');
    var expression = findNode.simple('text); // ref');
    expect(_flutter.identifyWidgetExpression(expression), expression);
  }

  Future<void>
      test_identifyWidgetExpression_parent_assignmentExpression() async {
    await resolveTestCode('''
import 'package:flutter/widgets.dart';

void f() {
  Widget text;
  text = Text('abc');
}

void useWidget(Widget w) {}
''');
    // Assignment itself.
    {
      var expression = findNode.simple('text =');
      expect(_flutter.identifyWidgetExpression(expression), isNull);
    }

    // Left hand side.
    {
      var expression = findNode.assignment('text =');
      expect(_flutter.identifyWidgetExpression(expression), isNull);
    }

    // Right hand side.
    {
      var expression = findNode.instanceCreation('Text(');
      expect(_flutter.identifyWidgetExpression(expression), expression);
    }
  }

  Future<void>
      test_identifyWidgetExpression_parent_conditionalExpression() async {
    await resolveTestCode('''
import 'package:flutter/widgets.dart';

void f(bool condition, Widget w1, Widget w2) {
  condition ? w1 : w2;
}
''');
    var thenWidget = findNode.simple('w1 :');
    expect(_flutter.identifyWidgetExpression(thenWidget), thenWidget);

    var elseWidget = findNode.simple('w2;');
    expect(_flutter.identifyWidgetExpression(elseWidget), elseWidget);
  }

  Future<void>
      test_identifyWidgetExpression_parent_expressionFunctionBody() async {
    await resolveTestCode('''
import 'package:flutter/widgets.dart';

void f(Widget widget) => widget; // ref
''');
    var expression = findNode.simple('widget; // ref');
    expect(_flutter.identifyWidgetExpression(expression), expression);
  }

  Future<void>
      test_identifyWidgetExpression_parent_expressionStatement() async {
    await resolveTestCode('''
import 'package:flutter/widgets.dart';

void f(Widget widget) {
  widget; // ref
}
''');
    var expression = findNode.simple('widget; // ref');
    expect(_flutter.identifyWidgetExpression(expression), expression);
  }

  Future<void> test_identifyWidgetExpression_parent_forElement() async {
    await resolveTestCode('''
import 'package:flutter/widgets.dart';

void f(bool b) {
  [
    for (var v in [0, 1, 2]) Container()
  ];
}

void useWidget(Widget w) {}
''');
    var expression = findNode.instanceCreation('Container()');
    expect(_flutter.identifyWidgetExpression(expression), expression);
  }

  Future<void> test_identifyWidgetExpression_parent_ifElement() async {
    await resolveTestCode('''
import 'package:flutter/widgets.dart';

void f(bool b) {
  [
    if (b)
      Text('then')
    else
      Text('else')
  ];
}

void useWidget(Widget w) {}
''');
    var thenExpression = findNode.instanceCreation("Text('then')");
    expect(_flutter.identifyWidgetExpression(thenExpression), thenExpression);

    var elseExpression = findNode.instanceCreation("Text('else')");
    expect(_flutter.identifyWidgetExpression(elseExpression), elseExpression);
  }

  Future<void> test_identifyWidgetExpression_parent_listLiteral() async {
    await resolveTestCode('''
import 'package:flutter/widgets.dart';

List<Widget> f(Widget widget) {
  return [widget]; // ref
}
''');
    var expression = findNode.simple('widget]; // ref');
    expect(_flutter.identifyWidgetExpression(expression), expression);
  }

  Future<void> test_identifyWidgetExpression_parent_namedExpression() async {
    await resolveTestCode('''
import 'package:flutter/widgets.dart';

void f() {
  var text = new Text('abc');
  useWidget(child: text); // ref
}

void useWidget({Widget child}) {}
''');
    var expression = findNode.simple('text); // ref');
    expect(_flutter.identifyWidgetExpression(expression), expression);
  }

  Future<void> test_identifyWidgetExpression_parent_returnStatement() async {
    await resolveTestCode('''
import 'package:flutter/widgets.dart';

Widget f(Widget widget) {
  return widget; // ref
}
''');
    var expression = findNode.simple('widget; // ref');
    expect(_flutter.identifyWidgetExpression(expression), expression);
  }

  Future<void> test_isWidget() async {
    await resolveTestCode('''
import 'package:flutter/widgets.dart';

class MyStatelessWidget extends StatelessWidget {}
class MyStatefulWidget extends StatefulWidget {}
class MyContainer extends Container {}
class NotFlutter {}
class NotWidget extends State {}
''');
    var myStatelessWidget = testUnitElement.getType('MyStatelessWidget');
    expect(_flutter.isWidget(myStatelessWidget), isTrue);

    var myStatefulWidget = testUnitElement.getType('MyStatefulWidget');
    expect(_flutter.isWidget(myStatefulWidget), isTrue);

    var myContainer = testUnitElement.getType('MyContainer');
    expect(_flutter.isWidget(myContainer), isTrue);

    var notFlutter = testUnitElement.getType('NotFlutter');
    expect(_flutter.isWidget(notFlutter), isFalse);

    var notWidget = testUnitElement.getType('NotWidget');
    expect(_flutter.isWidget(notWidget), isFalse);
  }

  Future<void> test_isWidgetCreation() async {
    await resolveTestCode('''
import 'package:flutter/widgets.dart';

var a = new Object();
var b = new Text('bbb');
''');
    expect(_flutter.isWidgetCreation(null), isFalse);

    var a = _getTopVariableCreation('a');
    expect(_flutter.isWidgetCreation(a), isFalse);

    var b = _getTopVariableCreation('b');
    expect(_flutter.isWidgetCreation(b), isTrue);
  }

  Future<void> test_isWidgetExpression() async {
    await resolveTestCode('''
import 'package:flutter/widgets.dart';

void f() {
  MyWidget.named(); // use
  var text = new Text('abc');
  text;
  createEmptyText();
  new Container(child: text);
  var intVariable = 42;
  intVariable;
}

class MyWidget extends StatelessWidget {
  MyWidget.named();
}

Text createEmptyText() => new Text('');
''');
    {
      var expression = findNode.simple('named(); // use');
      expect(_flutter.isWidgetExpression(expression), isFalse);
      var creation = expression.parent?.parent as InstanceCreationExpression;
      expect(_flutter.isWidgetExpression(creation), isTrue);
    }

    {
      var expression = findNode.instanceCreation("new Text('abc')");
      expect(_flutter.isWidgetExpression(expression), isTrue);
    }

    {
      var expression = findNode.simple('text;');
      expect(_flutter.isWidgetExpression(expression), isTrue);
    }

    {
      var expression = findNode.methodInvocation('createEmptyText();');
      expect(_flutter.isWidgetExpression(expression), isTrue);
    }

    {
      var expression = findNode.simple('Container(');
      expect(_flutter.isWidgetExpression(expression), isFalse);
    }

    {
      var expression = findNode.namedExpression('child: ');
      expect(_flutter.isWidgetExpression(expression), isFalse);
    }

    {
      var expression = findNode.integerLiteral('42;');
      expect(_flutter.isWidgetExpression(expression), isFalse);
    }

    {
      var expression = findNode.simple('intVariable;');
      expect(_flutter.isWidgetExpression(expression), isFalse);
    }
  }

  VariableDeclaration _getTopVariable(String name, [CompilationUnit? unit]) {
    unit ??= testUnit;
    for (var topDeclaration in unit.declarations) {
      if (topDeclaration is TopLevelVariableDeclaration) {
        for (var variable in topDeclaration.variables.variables) {
          if (variable.name2.lexeme == name) {
            return variable;
          }
        }
      }
    }
    fail('Not found $name in $unit');
  }

  InstanceCreationExpression _getTopVariableCreation(String name,
      [CompilationUnit? unit]) {
    return _getTopVariable(name, unit).initializer
        as InstanceCreationExpression;
  }
}
