// 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/services/correction/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';

const WIDGETS_LIBRARY_URI = 'package:flutter/widgets.dart';

const _BASIC_URI = "package:flutter/src/widgets/basic.dart";
const _CENTER_NAME = "Center";
const _CONTAINER_NAME = "Container";
const _CONTAINER_URI = "package:flutter/src/widgets/container.dart";
const _PADDING_NAME = "Padding";
const _STATE_NAME = "State";
const _STATEFUL_WIDGET_NAME = "StatefulWidget";
const _STATELESS_WIDGET_NAME = "StatelessWidget";
const _WIDGET_NAME = "Widget";
const _WIDGET_URI = "package:flutter/src/widgets/framework.dart";
final _frameworkUri = Uri.parse('package:flutter/src/widgets/framework.dart');

void convertChildToChildren(
    InstanceCreationExpression childArg,
    NamedExpression namedExp,
    String eol,
    Function getNodeText,
    Function getLinePrefix,
    Function getIndent,
    Function getText,
    Function _addInsertEdit,
    Function _addRemoveEdit,
    Function _addReplaceEdit,
    Function rangeNode) {
  int childLoc = namedExp.offset + 'child'.length;
  _addInsertEdit(childLoc, 'ren');
  int listLoc = childArg.offset;
  String childArgSrc = getNodeText(childArg);
  if (!childArgSrc.contains(eol)) {
    _addInsertEdit(listLoc, '<Widget>[');
    _addInsertEdit(listLoc + childArg.length, ']');
  } else {
    int newlineLoc = childArgSrc.lastIndexOf(eol);
    if (newlineLoc == childArgSrc.length) {
      newlineLoc -= 1;
    }
    String indentOld = getLinePrefix(childArg.offset + 1 + newlineLoc);
    String indentNew = '$indentOld${getIndent(1)}';
    // The separator includes 'child:' but that has no newlines.
    String separator =
        getText(namedExp.offset, childArg.offset - namedExp.offset);
    String prefix = separator.contains(eol) ? "" : "$eol$indentNew";
    if (prefix.isEmpty) {
      _addInsertEdit(namedExp.offset + 'child:'.length, ' <Widget>[');
      _addRemoveEdit(new SourceRange(childArg.offset - 2, 2));
    } else {
      _addInsertEdit(listLoc, '<Widget>[');
    }
    String newChildArgSrc = childArgSrc.replaceAll(
        new 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) {
  int childLoc = namedExp.offset + 'child'.length;
  builder.addSimpleInsertion(childLoc, 'ren');
  int listLoc = childArg.offset;
  String childArgSrc = getNodeText(childArg);
  if (!childArgSrc.contains(eol)) {
    builder.addSimpleInsertion(listLoc, '<Widget>[');
    builder.addSimpleInsertion(listLoc + childArg.length, ']');
  } else {
    int newlineLoc = childArgSrc.lastIndexOf(eol);
    if (newlineLoc == childArgSrc.length) {
      newlineLoc -= 1;
    }
    String indentOld = getLinePrefix(childArg.offset + 1 + newlineLoc);
    String indentNew = '$indentOld${getIndent(1)}';
    // The separator includes 'child:' but that has no newlines.
    String separator =
        getText(namedExp.offset, childArg.offset - namedExp.offset);
    String prefix = separator.contains(eol) ? "" : "$eol$indentNew";
    if (prefix.isEmpty) {
      builder.addSimpleInsertion(
          namedExp.offset + 'child:'.length, ' <Widget>[');
      builder.addDeletion(new SourceRange(childArg.offset - 2, 2));
    } else {
      builder.addSimpleInsertion(listLoc, '<Widget>[');
    }
    String newChildArgSrc = childArgSrc.replaceAll(
        new 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) {
  NamedExpression child = findChildArgument(newExpr);
  return getChildWidget(child);
}

/**
 * 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) {
  Expression expression = child?.expression;
  if (isWidgetExpression(expression)) {
    return expression;
  }
  return null;
}

/**
 * Return the presentation for the given Flutter `Widget` creation [node].
 */
String getWidgetPresentationText(InstanceCreationExpression node) {
  ClassElement element = node.staticElement?.enclosingElement;
  if (!isWidget(element)) {
    return null;
  }
  List<Expression> arguments = node.argumentList.arguments;
  if (_isExactWidget(
      element, 'Icon', 'package:flutter/src/widgets/icon.dart')) {
    if (arguments.isNotEmpty) {
      String text = arguments[0].toString();
      String arg = shorten(text, 32);
      return 'Icon($arg)';
    } else {
      return 'Icon';
    }
  }
  if (_isExactWidget(
      element, 'Text', 'package:flutter/src/widgets/text.dart')) {
    if (arguments.isNotEmpty) {
      String text = arguments[0].toString();
      String 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 a Flutter `Widget`.  Return `null` if nothing found.
 */
Expression identifyWidgetExpression(AstNode node) {
  for (; node != null; node = node.parent) {
    if (isWidgetExpression(node)) {
      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 Flutter class `StatefulWidget`.
 */
bool isExactlyStatefulWidgetType(DartType type) {
  return type is InterfaceType &&
      _isExactWidget(type.element, _STATEFUL_WIDGET_NAME, _WIDGET_URI);
}

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

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

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

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

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

/**
 * Return `true` if the given [type] is the Flutter class `Widget`, or its
 * subtype.
 */
bool isListOfWidgetsType(DartType type) {
  return type is InterfaceType &&
      type.element.library.isDartCore &&
      type.element.name == 'List' &&
      type.typeArguments.length == 1 &&
      isWidgetType(type.typeArguments[0]);
}

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

/**
 * 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, _WIDGET_NAME, _WIDGET_URI)) {
    return true;
  }
  for (InterfaceType type in element.allSupertypes) {
    if (_isExactWidget(type.element, _WIDGET_NAME, _WIDGET_URI)) {
      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) {
  ClassElement element = expr?.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 (InterfaceType type in element.allSupertypes) {
    if (type.name == requiredName) {
      Uri 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, String uri) {
  return element != null &&
      element.name == type &&
      element.source.uri.toString() == uri;
}
