// 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/strings.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';

class Flutter {
  static final Flutter instance = Flutter();

  static const _nameAlign = 'Align';
  static const _nameCenter = 'Center';
  static const _nameContainer = 'Container';
  static const _namePadding = 'Padding';
  static const _nameState = 'State';
  static const _nameStatefulWidget = 'StatefulWidget';
  static const _nameStatelessWidget = 'StatelessWidget';
  static const _nameStreamBuilder = 'StreamBuilder';
  static const _nameWidget = 'Widget';

  final String widgetsUri = 'package:flutter/widgets.dart';

  final Uri _uriAlignment = Uri.parse(
    'package:flutter/src/painting/alignment.dart',
  );
  final Uri _uriAsync = Uri.parse(
    'package:flutter/src/widgets/async.dart',
  );
  final Uri _uriBasic = Uri.parse(
    'package:flutter/src/widgets/basic.dart',
  );
  final Uri _uriContainer = Uri.parse(
    'package:flutter/src/widgets/container.dart',
  );
  final Uri _uriEdgeInsets = Uri.parse(
    'package:flutter/src/painting/edge_insets.dart',
  );
  final Uri _uriFramework = Uri.parse(
    'package:flutter/src/widgets/framework.dart',
  );
  final Uri _uriWidgetsIcon = Uri.parse(
    'package:flutter/src/widgets/icon.dart',
  );
  final Uri _uriWidgetsText = Uri.parse(
    'package:flutter/src/widgets/text.dart',
  );

  /// Return the argument with the given [index], or `null` if none.
  Expression argumentByIndex(List<Expression> arguments, int index) {
    if (index < arguments.length) {
      return arguments[index];
    }
    return null;
  }

  /// Return the named expression with the given [name], or `null` if none.
  NamedExpression argumentByName(List<Expression> arguments, String name) {
    for (var argument in arguments) {
      if (argument is NamedExpression && argument.name.label.name == name) {
        return argument;
      }
    }
    return null;
  }

  void convertChildToChildren(
      InstanceCreationExpression childArg,
      NamedExpression namedExp,
      String eol,
      Function getNodeText,
      Function getLinePrefix,
      Function getIndent,
      Function getText,
      Function _addInsertEdit,
      Function _addRemoveEdit,
      Function _addReplaceEdit,
      Function rangeNode) {
    var childLoc = namedExp.offset + 'child'.length;
    _addInsertEdit(childLoc, 'ren');
    var listLoc = childArg.offset;
    String childArgSrc = getNodeText(childArg);
    if (!childArgSrc.contains(eol)) {
      _addInsertEdit(listLoc, '[');
      _addInsertEdit(listLoc + childArg.length, ']');
    } else {
      var newlineLoc = childArgSrc.lastIndexOf(eol);
      if (newlineLoc == childArgSrc.length) {
        newlineLoc -= 1;
      }
      String indentOld = getLinePrefix(childArg.offset + 1 + newlineLoc);
      var indentNew = '$indentOld${getIndent(1)}';
      // The separator includes 'child:' but that has no newlines.
      String separator =
          getText(namedExp.offset, childArg.offset - namedExp.offset);
      var prefix = separator.contains(eol) ? '' : '$eol$indentNew';
      if (prefix.isEmpty) {
        _addInsertEdit(namedExp.offset + 'child:'.length, ' [');
        _addRemoveEdit(SourceRange(childArg.offset - 2, 2));
      } else {
        _addInsertEdit(listLoc, '[');
      }
      var newChildArgSrc = childArgSrc.replaceAll(
          RegExp('^$indentOld', multiLine: true), '$indentNew');
      newChildArgSrc = '$prefix$newChildArgSrc,$eol$indentOld]';
      _addReplaceEdit(rangeNode(childArg), newChildArgSrc);
    }
  }

  void convertChildToChildren2(
      DartFileEditBuilder builder,
      Expression childArg,
      NamedExpression namedExp,
      String eol,
      Function getNodeText,
      Function getLinePrefix,
      Function getIndent,
      Function getText,
      Function rangeNode) {
    var childLoc = namedExp.offset + 'child'.length;
    builder.addSimpleInsertion(childLoc, 'ren');
    var listLoc = childArg.offset;
    String childArgSrc = getNodeText(childArg);
    if (!childArgSrc.contains(eol)) {
      builder.addSimpleInsertion(listLoc, '[');
      builder.addSimpleInsertion(listLoc + childArg.length, ']');
    } else {
      var newlineLoc = childArgSrc.lastIndexOf(eol);
      if (newlineLoc == childArgSrc.length) {
        newlineLoc -= 1;
      }
      String indentOld = getLinePrefix(childArg.offset + 1 + newlineLoc);
      var indentNew = '$indentOld${getIndent(1)}';
      // The separator includes 'child:' but that has no newlines.
      String separator =
          getText(namedExp.offset, childArg.offset - namedExp.offset);
      var prefix = separator.contains(eol) ? '' : '$eol$indentNew';
      if (prefix.isEmpty) {
        builder.addSimpleInsertion(namedExp.offset + 'child:'.length, ' [');
        builder.addDeletion(SourceRange(childArg.offset - 2, 2));
      } else {
        builder.addSimpleInsertion(listLoc, '[');
      }
      var newChildArgSrc = childArgSrc.replaceAll(
          RegExp('^$indentOld', multiLine: true), '$indentNew');
      newChildArgSrc = '$prefix$newChildArgSrc,$eol$indentOld]';
      builder.addSimpleReplacement(rangeNode(childArg), newChildArgSrc);
    }
  }

  /// Return the named expression representing the `child` argument of the given
  /// [newExpr], or `null` if none.
  NamedExpression findChildArgument(InstanceCreationExpression newExpr) =>
      newExpr.argumentList.arguments
          .firstWhere(isChildArgument, orElse: () => null);

  /// Return the named expression representing the `children` argument of the
  /// given [newExpr], or `null` if none.
  NamedExpression findChildrenArgument(InstanceCreationExpression newExpr) =>
      newExpr.argumentList.arguments
          .firstWhere(isChildrenArgument, orElse: () => null);

  /// Return the Flutter instance creation expression that is the value of the
  /// 'child' argument of the given [newExpr], or null if none.
  InstanceCreationExpression findChildWidget(
      InstanceCreationExpression newExpr) {
    var child = findChildArgument(newExpr);
    return getChildWidget(child);
  }

  /// Return the named expression with the given [name], or `null` if none.
  NamedExpression findNamedArgument(
    InstanceCreationExpression creation,
    String name,
  ) {
    var arguments = creation.argumentList.arguments;
    return argumentByName(arguments, name);
  }

  /// If the given [node] is a simple identifier, find the named expression
  /// whose name is the given [name] that is an argument to a Flutter instance
  /// creation expression. Return null if any condition cannot be satisfied.
  NamedExpression findNamedExpression(AstNode node, String name) {
    if (node is! SimpleIdentifier) {
      return null;
    }
    SimpleIdentifier namedArg = node;
    NamedExpression namedExp;
    if (namedArg.parent is Label && namedArg.parent.parent is NamedExpression) {
      namedExp = namedArg.parent.parent;
      if (namedArg.name != name || namedExp.expression == null) {
        return null;
      }
    } else {
      return null;
    }
    if (namedExp.parent?.parent is! InstanceCreationExpression) {
      return null;
    }
    InstanceCreationExpression newExpr = namedExp.parent.parent;
    if (newExpr == null || !isWidgetCreation(newExpr)) {
      return null;
    }
    return namedExp;
  }

  /// Return the expression that is a Flutter Widget that is the value of the
  /// given [child], or null if none.
  Expression getChildWidget(NamedExpression child) {
    var expression = child?.expression;
    if (isWidgetExpression(expression)) {
      return expression;
    }
    return null;
  }

  /// Return the presentation for the given Flutter `Widget` creation [node].
  String getWidgetPresentationText(InstanceCreationExpression node) {
    var element = node.constructorName.staticElement?.enclosingElement;
    if (!isWidget(element)) {
      return null;
    }
    List<Expression> arguments = node.argumentList.arguments;
    if (_isExactWidget(element, 'Icon', _uriWidgetsIcon)) {
      if (arguments.isNotEmpty) {
        var text = arguments[0].toString();
        var arg = shorten(text, 32);
        return 'Icon($arg)';
      } else {
        return 'Icon';
      }
    }
    if (_isExactWidget(element, 'Text', _uriWidgetsText)) {
      if (arguments.isNotEmpty) {
        var text = arguments[0].toString();
        var arg = shorten(text, 32);
        return 'Text($arg)';
      } else {
        return 'Text';
      }
    }
    return element.name;
  }

  /// Return the instance creation expression that surrounds the given
  /// [node], if any, else null. The [node] may be the instance creation
  /// expression itself or the identifier that names the constructor.
  InstanceCreationExpression identifyNewExpression(AstNode node) {
    InstanceCreationExpression newExpr;
    if (node is SimpleIdentifier) {
      if (node.parent is ConstructorName &&
          node.parent.parent is InstanceCreationExpression) {
        newExpr = node.parent.parent;
      } else if (node.parent?.parent is ConstructorName &&
          node.parent.parent?.parent is InstanceCreationExpression) {
        newExpr = node.parent.parent.parent;
      }
    } else if (node is InstanceCreationExpression) {
      newExpr = node;
    }
    return newExpr;
  }

  /// Attempt to find and return the closest expression that encloses the [node]
  /// and is an independent Flutter `Widget`.  Return `null` if nothing found.
  Expression identifyWidgetExpression(AstNode node) {
    for (; node != null; node = node.parent) {
      if (isWidgetExpression(node)) {
        var parent = node.parent;

        if (node is AssignmentExpression) {
          return null;
        }
        if (parent is AssignmentExpression) {
          if (parent.rightHandSide == node) {
            return node;
          }
          return null;
        }

        if (parent is ArgumentList ||
            parent is ConditionalExpression && parent.thenExpression == node ||
            parent is ConditionalExpression && parent.elseExpression == node ||
            parent is ExpressionFunctionBody && parent.expression == node ||
            parent is ForElement && parent.body == node ||
            parent is IfElement && parent.thenElement == node ||
            parent is IfElement && parent.elseElement == node ||
            parent is ListLiteral ||
            parent is NamedExpression && parent.expression == node ||
            parent is Statement) {
          return node;
        }
      }
      if (node is ArgumentList || node is Statement || node is FunctionBody) {
        return null;
      }
    }
    return null;
  }

  /// Return `true` is the given [argument] is the `child` argument.
  bool isChildArgument(Expression argument) =>
      argument is NamedExpression && argument.name.label.name == 'child';

  /// Return `true` is the given [argument] is the `child` argument.
  bool isChildrenArgument(Expression argument) =>
      argument is NamedExpression && argument.name.label.name == 'children';

  /// Return `true` if the given [type] is the dart.ui class `Color`, or its
  /// subtype.
  bool isColor(DartType type) {
    if (type is! InterfaceType) {
      return false;
    }

    bool isColorElement(ClassElement element) {
      if (element == null) {
        return false;
      }

      bool isExactColor(ClassElement element) =>
          element?.name == 'Color' && element.library.name == 'dart.ui';
      if (isExactColor(element)) {
        return true;
      }
      for (var type in element.allSupertypes) {
        if (isExactColor(type.element)) {
          return true;
        }
      }
      return false;
    }

    return isColorElement(type.element);
  }

  /// Return `true` if the [element] is the Flutter class `Alignment`.
  bool isExactAlignment(ClassElement element) {
    return _isExactWidget(element, 'Alignment', _uriAlignment);
  }

  /// Return `true` if the [element] is the Flutter class
  /// `AlignmentDirectional`.
  bool isExactAlignmentDirectional(ClassElement element) {
    return _isExactWidget(element, 'AlignmentDirectional', _uriAlignment);
  }

  /// Return `true` if the [element] is the Flutter class `AlignmentGeometry`.
  bool isExactAlignmentGeometry(ClassElement element) {
    return _isExactWidget(element, 'AlignmentGeometry', _uriAlignment);
  }

  /// Return `true` if the [type] is the Flutter type `EdgeInsetsGeometry`.
  bool isExactEdgeInsetsGeometryType(DartType type) {
    return type is InterfaceType &&
        _isExactWidget(type.element, 'EdgeInsetsGeometry', _uriEdgeInsets);
  }

  /// Return `true` if the [node] is creation of `Align`.
  bool isExactlyAlignCreation(InstanceCreationExpression node) {
    var type = node?.staticType;
    return isExactWidgetTypeAlign(type);
  }

  /// Return `true` if the [node] is creation of `Container`.
  bool isExactlyContainerCreation(InstanceCreationExpression node) {
    var type = node?.staticType;
    return isExactWidgetTypeContainer(type);
  }

  /// Return `true` if the [node] is creation of `Padding`.
  bool isExactlyPaddingCreation(InstanceCreationExpression node) {
    var type = node?.staticType;
    return isExactWidgetTypePadding(type);
  }

  /// Return `true` if the given [type] is the Flutter class `StatefulWidget`.
  bool isExactlyStatefulWidgetType(DartType type) {
    return type is InterfaceType &&
        _isExactWidget(type.element, _nameStatefulWidget, _uriFramework);
  }

  /// Return `true` if the given [type] is the Flutter class `StatelessWidget`.
  bool isExactlyStatelessWidgetType(DartType type) {
    return type is InterfaceType &&
        _isExactWidget(type.element, _nameStatelessWidget, _uriFramework);
  }

  /// Return `true` if the given [element] is the Flutter class `State`.
  bool isExactState(ClassElement element) {
    return _isExactWidget(element, _nameState, _uriFramework);
  }

  /// Return `true` if the given [type] is the Flutter class `Align`.
  bool isExactWidgetTypeAlign(DartType type) {
    return type is InterfaceType &&
        _isExactWidget(type.element, _nameAlign, _uriBasic);
  }

  /// Return `true` if the given [type] is the Flutter class `Center`.
  bool isExactWidgetTypeCenter(DartType type) {
    return type is InterfaceType &&
        _isExactWidget(type.element, _nameCenter, _uriBasic);
  }

  /// Return `true` if the given [type] is the Flutter class `Container`.
  bool isExactWidgetTypeContainer(DartType type) {
    return type is InterfaceType &&
        _isExactWidget(type.element, _nameContainer, _uriContainer);
  }

  /// Return `true` if the given [type] is the Flutter class `Padding`.
  bool isExactWidgetTypePadding(DartType type) {
    return type is InterfaceType &&
        _isExactWidget(type.element, _namePadding, _uriBasic);
  }

  /// Return `true` if the given [type] is the Flutter class `StreamBuilder`.
  bool isExactWidgetTypeStreamBuilder(DartType type) {
    return type is InterfaceType &&
        _isExactWidget(type.element, _nameStreamBuilder, _uriAsync);
  }

  /// Return `true` if the given [type] is the Flutter class `Widget`, or its
  /// subtype.
  bool isListOfWidgetsType(DartType type) {
    return type is InterfaceType &&
        type.isDartCoreList &&
        isWidgetType(type.typeArguments[0]);
  }

  /// Return `true` if the given [type] is the dart.ui class `Color`, or its
  /// subtype.
  bool isMatrix4(DartType type) {
    if (type is! InterfaceType) {
      return false;
    }

    bool isMatrix4Element(ClassElement element) {
      if (element == null) {
        return false;
      }

      bool isExactMatrix4(ClassElement element) =>
          element?.name == 'Matrix4' &&
          element.library.name == 'vector_math_64';
      if (isExactMatrix4(element)) {
        return true;
      }
      for (var type in element.allSupertypes) {
        if (isExactMatrix4(type.element)) {
          return true;
        }
      }
      return false;
    }

    return isMatrix4Element(type.element);
  }

  /// Return `true` if the given [element] has the Flutter class `State` as
  /// a superclass.
  bool isState(ClassElement element) {
    return _hasSupertype(element, _uriFramework, _nameState);
  }

  /// Return `true` if the given [element] is a [ClassElement] that extends
  /// the Flutter class `StatefulWidget`.
  bool isStatefulWidgetDeclaration(Element element) {
    if (element is ClassElement) {
      return isExactlyStatefulWidgetType(element.supertype);
    }
    return false;
  }

  /// Return `true` if the given [element] is the Flutter class `Widget`, or its
  /// subtype.
  bool isWidget(ClassElement element) {
    if (element == null) {
      return false;
    }
    if (_isExactWidget(element, _nameWidget, _uriFramework)) {
      return true;
    }
    for (var type in element.allSupertypes) {
      if (_isExactWidget(type.element, _nameWidget, _uriFramework)) {
        return true;
      }
    }
    return false;
  }

  /// Return `true` if the given [expr] is a constructor invocation for a
  /// class that has the Flutter class `Widget` as a superclass.
  bool isWidgetCreation(InstanceCreationExpression expr) {
    var element = expr?.constructorName?.staticElement?.enclosingElement;
    return isWidget(element);
  }

  /// Return `true` if the given [node] is the Flutter class `Widget`, or its
  /// subtype.
  bool isWidgetExpression(AstNode node) {
    if (node == null) {
      return false;
    }
    if (node.parent is TypeName || node.parent?.parent is TypeName) {
      return false;
    }
    if (node.parent is ConstructorName) {
      return false;
    }
    if (node is NamedExpression) {
      return false;
    }
    if (node is Expression) {
      return isWidgetType(node.staticType);
    }
    return false;
  }

  /// Return `true` if the given [type] is the Flutter class `Widget`, or its
  /// subtype.
  bool isWidgetType(DartType type) {
    return type is InterfaceType && isWidget(type.element);
  }

  /// Return `true` if the given [element] has a supertype with the
  /// [requiredName] defined in the file with the [requiredUri].
  bool _hasSupertype(
      ClassElement element, Uri requiredUri, String requiredName) {
    if (element == null) {
      return false;
    }
    for (var type in element.allSupertypes) {
      if (type.element.name == requiredName) {
        var uri = type.element.source.uri;
        if (uri == requiredUri) {
          return true;
        }
      }
    }
    return false;
  }

  /// Return `true` if the given [element] is the exact [type] defined in the
  /// file with the given [uri].
  bool _isExactWidget(ClassElement element, String type, Uri uri) {
    return element != null && element.name == type && element.source.uri == uri;
  }
}
