// Copyright (c) 2019, 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/protocol_server.dart' as protocol;
import 'package:analysis_server/src/services/flutter/class_description.dart';
import 'package:analysis_server/src/services/flutter/property.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analyzer/dart/analysis/results.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/dart/analysis/session_helper.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:dart_style/dart_style.dart';

/// The result of [WidgetDescriptions.setPropertyValue] invocation.
class SetPropertyValueResult {
  /// The error to report to the client, or `null` if OK.
  final protocol.RequestErrorCode errorCode;

  /// The change to apply, or `null` if [errorCode] is not `null`.
  final protocol.SourceChange change;

  SetPropertyValueResult._({this.errorCode, this.change});
}

class WidgetDescriptions {
  final ClassDescriptionRegistry _classRegistry = ClassDescriptionRegistry();

  /// The mapping of identifiers of previously returned properties.
  final Map<int, PropertyDescription> _properties = {};

  /// Flush all data, because there was a change to a file.
  void flush() {
    _classRegistry.flush();
    _properties.clear();
  }

  /// Return the description of the widget with [InstanceCreationExpression] in
  /// the [resolvedUnit] at the [offset], or `null` if the location does not
  /// correspond to a widget.
  Future<protocol.FlutterGetWidgetDescriptionResult> getDescription(
    ResolvedUnitResult resolvedUnit,
    int offset,
  ) async {
    var computer = _WidgetDescriptionComputer(
      _classRegistry,
      resolvedUnit,
      offset,
    );
    var widgetDescription = await computer.compute();

    if (widgetDescription == null) {
      return null;
    }

    var protocolProperties = _toProtocolProperties(
      widgetDescription.properties,
    );
    return protocol.FlutterGetWidgetDescriptionResult(protocolProperties);
  }

  Future<SetPropertyValueResult> setPropertyValue(
    int id,
    protocol.FlutterWidgetPropertyValue value,
  ) async {
    var property = _properties[id];
    if (property == null) {
      return SetPropertyValueResult._(
        errorCode: protocol
            .RequestErrorCode.FLUTTER_SET_WIDGET_PROPERTY_VALUE_INVALID_ID,
      );
    }

    if (value == null) {
      if (property.protocolProperty.isRequired) {
        return SetPropertyValueResult._(
          errorCode: protocol
              .RequestErrorCode.FLUTTER_SET_WIDGET_PROPERTY_VALUE_IS_REQUIRED,
        );
      }
      var change = await property.removeValue();
      return SetPropertyValueResult._(change: change);
    } else {
      try {
        var change = await property.changeValue(value);
        return SetPropertyValueResult._(change: change);
      } on FormatterException {
        return SetPropertyValueResult._(
          errorCode: protocol.RequestErrorCode
              .FLUTTER_SET_WIDGET_PROPERTY_VALUE_INVALID_EXPRESSION,
        );
      }
    }
  }

  List<protocol.FlutterWidgetProperty> _toProtocolProperties(
    List<PropertyDescription> properties,
  ) {
    var protocolProperties = <protocol.FlutterWidgetProperty>[];
    for (var property in properties) {
      var protocolProperty = property.protocolProperty;

      _properties[protocolProperty.id] = property;

      protocolProperty.children = _toProtocolProperties(property.children);
      protocolProperties.add(protocolProperty);
    }
    return protocolProperties;
  }
}

class _WidgetDescription {
  final List<PropertyDescription> properties;

  _WidgetDescription(this.properties);
}

class _WidgetDescriptionComputer {
  final ClassDescriptionRegistry classRegistry;

  /// The set of classes for which we are currently adding properties,
  /// used to prevent infinite recursion.
  final Set<ClassElement> classesBeingProcessed = <ClassElement>{};

  /// The resolved unit with the widget [InstanceCreationExpression].
  final ResolvedUnitResult resolvedUnit;

  /// The offset of the widget expression.
  final int widgetOffset;

  ClassElement _classAlignment;
  ClassElement _classAlignmentDirectional;
  ClassElement _classContainer;
  ClassElement _classEdgeInsets;

  _WidgetDescriptionComputer(
    this.classRegistry,
    this.resolvedUnit,
    this.widgetOffset,
  );

  Flutter get _flutter => Flutter.instance;

  Future<_WidgetDescription> compute() async {
    var node = NodeLocator2(widgetOffset).searchWithin(resolvedUnit.unit);
    var instanceCreation = _flutter.identifyNewExpression(node);
    if (instanceCreation == null) {
      return null;
    }

    var constructorElement = instanceCreation.constructorName.staticElement;
    if (constructorElement == null) {
      return null;
    }

    await _fetchClassElements();

    var properties = <PropertyDescription>[];
    _addProperties(
      properties: properties,
      instanceCreation: instanceCreation,
    );
    _addContainerProperty(properties, instanceCreation);

    return _WidgetDescription(properties);
  }

  void _addContainerProperty(
    List<PropertyDescription> properties,
    InstanceCreationExpression widgetCreation,
  ) {
    if (!_flutter.isWidgetCreation(widgetCreation)) {
      return;
    }

    InstanceCreationExpression parentCreation;
    var childArgument = widgetCreation.parent;
    if (childArgument is NamedExpression &&
        childArgument.name.label.name == 'child') {
      var argumentList = childArgument.parent;
      var argumentListParent = argumentList.parent;
      if (argumentList is ArgumentList &&
          argumentListParent is InstanceCreationExpression) {
        parentCreation = argumentListParent;
      }
    }

    PropertyDescription containerProperty;
    if (_flutter.isExactlyContainerCreation(parentCreation)) {
      containerProperty = PropertyDescription(
        resolvedUnit: resolvedUnit,
        instanceCreation: parentCreation,
        protocolProperty: protocol.FlutterWidgetProperty(
          PropertyDescription.nextId(),
          true,
          false,
          'Container',
        ),
      );
      properties.add(containerProperty);

      _addProperties(
        properties: containerProperty.children,
        parent: containerProperty,
        instanceCreation: parentCreation,
      );

      containerProperty.children.removeWhere(
        (property) => property.name == 'child',
      );
    } else {
      var containerDescription = classRegistry.get(_classContainer);
      containerProperty = PropertyDescription(
        resolvedUnit: resolvedUnit,
        classDescription: containerDescription,
        protocolProperty: protocol.FlutterWidgetProperty(
          PropertyDescription.nextId(),
          true,
          false,
          'Container',
        ),
        virtualContainer: VirtualContainerProperty(
          _classContainer,
          widgetCreation,
        ),
      );
      properties.add(containerProperty);

      _addProperties(
        properties: containerProperty.children,
        parent: containerProperty,
        classDescription: containerDescription,
      );

      if (_flutter.isExactlyAlignCreation(parentCreation) &&
          _flutter.findNamedArgument(parentCreation, 'widthFactor') == null &&
          _flutter.findNamedArgument(parentCreation, 'heightFactor') == null) {
        _replaceNestedContainerProperty(
          containerProperty,
          parentCreation,
          'alignment',
        );
      }

      if (_flutter.isExactlyPaddingCreation(parentCreation)) {
        _replaceNestedContainerProperty(
          containerProperty,
          parentCreation,
          'padding',
        );
      }
    }

    containerProperty.children.removeWhere(
      (property) => property.name == 'child',
    );
  }

  void _addProperties({
    List<PropertyDescription> properties,
    PropertyDescription parent,
    ClassDescription classDescription,
    InstanceCreationExpression instanceCreation,
    ConstructorElement constructorElement,
  }) {
    constructorElement ??= instanceCreation?.constructorName?.staticElement;
    constructorElement ??= classDescription?.constructor;
    if (constructorElement == null) return;

    var classElement = constructorElement.enclosingElement;
    if (!classesBeingProcessed.add(classElement)) return;

    var existingNamed = <String>{};
    if (instanceCreation != null) {
      for (var argumentExpression in instanceCreation.argumentList.arguments) {
        var parameter = argumentExpression.staticParameterElement;
        if (parameter == null) continue;

        Expression valueExpression;
        if (argumentExpression is NamedExpression) {
          valueExpression = argumentExpression.expression;
          existingNamed.add(parameter.name);
        } else {
          valueExpression = argumentExpression;
        }

        _addProperty(
          properties: properties,
          parent: parent,
          parameter: parameter,
          classDescription: classDescription,
          instanceCreation: instanceCreation,
          argumentExpression: argumentExpression,
          valueExpression: valueExpression,
        );
      }
    }

    for (var parameter in constructorElement.parameters) {
      if (!parameter.isNamed) continue;
      if (existingNamed.contains(parameter.name)) continue;

      _addProperty(
        properties: properties,
        parent: parent,
        parameter: parameter,
        classDescription: classDescription,
        instanceCreation: instanceCreation,
      );
    }

    classesBeingProcessed.remove(classElement);
  }

  void _addProperty({
    List<PropertyDescription> properties,
    PropertyDescription parent,
    ParameterElement parameter,
    ClassDescription classDescription,
    InstanceCreationExpression instanceCreation,
    Expression argumentExpression,
    Expression valueExpression,
  }) {
    var documentation = getParameterDocumentation(parameter);

    String valueExpressionCode;
    if (valueExpression != null) {
      valueExpressionCode = resolvedUnit.content.substring(
        valueExpression.offset,
        valueExpression.end,
      );
    }

    var isSafeToUpdate = false;
    protocol.FlutterWidgetPropertyValue value;
    if (valueExpression != null) {
      value = _toValue(valueExpression);
      isSafeToUpdate = value != null;
    } else {
      isSafeToUpdate = true;
    }

    var propertyDescription = PropertyDescription(
      parent: parent,
      resolvedUnit: resolvedUnit,
      flutter: _flutter,
      classDescription: classDescription,
      instanceCreation: instanceCreation,
      argumentExpression: argumentExpression,
      valueExpression: valueExpression,
      parameterElement: parameter,
      protocolProperty: protocol.FlutterWidgetProperty(
        PropertyDescription.nextId(),
        parameter.isRequiredPositional,
        isSafeToUpdate,
        parameter.name,
        documentation: documentation,
        editor: _getEditor(parameter.type),
        expression: valueExpressionCode,
        value: value,
      ),
    );
    properties.add(propertyDescription);

    if (_flutter.isExactEdgeInsetsGeometryType(parameter.type)) {
      propertyDescription.addEdgeInsetsNestedProperties(_classEdgeInsets);
    } else if (valueExpression is InstanceCreationExpression) {
      var type = valueExpression.staticType;
      if (classRegistry.hasNestedProperties(type)) {
        _addProperties(
          properties: propertyDescription.children,
          parent: propertyDescription,
          instanceCreation: valueExpression,
        );
      }
    } else if (valueExpression == null) {
      var type = parameter.type;
      if (type is InterfaceType) {
        var classDescription = classRegistry.get(
          type.element,
        );
        if (classDescription != null) {
          _addProperties(
            properties: propertyDescription.children,
            parent: propertyDescription,
            classDescription: classDescription,
          );
        }
      }
    }
  }

  List<protocol.FlutterWidgetPropertyValueEnumItem> _enumItemsForEnum(
    ClassElement element,
  ) {
    return element.fields
        .where((field) => field.isStatic && field.isEnumConstant)
        .map(_toEnumItem)
        .toList();
  }

  List<protocol.FlutterWidgetPropertyValueEnumItem> _enumItemsForStaticFields(
      ClassElement classElement) {
    return classElement.fields
        .where((f) => f.isStatic)
        .map(_toEnumItem)
        .toList();
  }

  Future<void> _fetchClassElements() async {
    var sessionHelper = AnalysisSessionHelper(resolvedUnit.session);
    _classAlignment = await sessionHelper.getClass(
      _flutter.widgetsUri,
      'Alignment',
    );
    _classAlignmentDirectional = await sessionHelper.getClass(
      _flutter.widgetsUri,
      'AlignmentDirectional',
    );
    _classContainer = await sessionHelper.getClass(
      _flutter.widgetsUri,
      'Container',
    );
    _classEdgeInsets = await sessionHelper.getClass(
      _flutter.widgetsUri,
      'EdgeInsets',
    );
  }

  protocol.FlutterWidgetPropertyEditor _getEditor(DartType type) {
    if (type.isDartCoreBool) {
      return protocol.FlutterWidgetPropertyEditor(
        protocol.FlutterWidgetPropertyEditorKind.BOOL,
      );
    }
    if (type.isDartCoreDouble) {
      return protocol.FlutterWidgetPropertyEditor(
        protocol.FlutterWidgetPropertyEditorKind.DOUBLE,
      );
    }
    if (type.isDartCoreInt) {
      return protocol.FlutterWidgetPropertyEditor(
        protocol.FlutterWidgetPropertyEditorKind.INT,
      );
    }
    if (type.isDartCoreString) {
      return protocol.FlutterWidgetPropertyEditor(
        protocol.FlutterWidgetPropertyEditorKind.STRING,
      );
    }
    if (type is InterfaceType) {
      var classElement = type.element;
      if (classElement.isEnum) {
        return protocol.FlutterWidgetPropertyEditor(
          protocol.FlutterWidgetPropertyEditorKind.ENUM,
          enumItems: _enumItemsForEnum(classElement),
        );
      }
      if (_flutter.isExactAlignmentGeometry(classElement)) {
        var items = <protocol.FlutterWidgetPropertyValueEnumItem>[];
        items.addAll(
          _enumItemsForStaticFields(_classAlignment),
        );
        items.addAll(
          _enumItemsForStaticFields(_classAlignmentDirectional),
        );
        return protocol.FlutterWidgetPropertyEditor(
          protocol.FlutterWidgetPropertyEditorKind.ENUM_LIKE,
          enumItems: items,
        );
      }
    }
    return null;
  }

  /// If the [parentCreation] has a property with the given [name], replace
  /// with it the corresponding nested property of the [containerProperty].
  void _replaceNestedContainerProperty(
    PropertyDescription containerProperty,
    InstanceCreationExpression parentCreation,
    String name,
  ) {
    var argument = _flutter.findNamedArgument(parentCreation, name);
    if (argument != null) {
      var replacements = <PropertyDescription>[];
      _addProperty(
        properties: replacements,
        parent: containerProperty,
        parameter: argument.staticParameterElement,
        instanceCreation: parentCreation,
        argumentExpression: argument,
        valueExpression: argument.expression,
      );

      var replacement = replacements[0];
      if (replacement != null) {
        containerProperty.replaceChild(name, replacement);
        containerProperty.virtualContainer.setParentCreation(
          parentCreation,
          argument,
        );
      }
    }
  }

  protocol.FlutterWidgetPropertyValueEnumItem _toEnumItem(FieldElement field) {
    var classElement = field.enclosingElement as ClassElement;
    var libraryUriStr = '${classElement.library.source.uri}';
    var documentation = getFieldDocumentation(field);

    return protocol.FlutterWidgetPropertyValueEnumItem(
      libraryUriStr,
      classElement.name,
      field.name,
      documentation: documentation,
    );
  }

  protocol.FlutterWidgetPropertyValue _toValue(Expression valueExpression) {
    if (valueExpression is BooleanLiteral) {
      return protocol.FlutterWidgetPropertyValue(
        boolValue: valueExpression.value,
      );
    } else if (valueExpression is DoubleLiteral) {
      return protocol.FlutterWidgetPropertyValue(
        doubleValue: valueExpression.value,
      );
    } else if (valueExpression is Identifier) {
      var element = valueExpression.staticElement;
      if (element is PropertyAccessorElement && element.isGetter) {
        var field = element.variable;
        if (field is FieldElement && field.isStatic) {
          var enclosingClass = field.enclosingElement as ClassElement;
          if (field.isEnumConstant ||
              _flutter.isExactAlignment(enclosingClass) ||
              _flutter.isExactAlignmentDirectional(enclosingClass)) {
            return protocol.FlutterWidgetPropertyValue(
              enumValue: _toEnumItem(field),
            );
          }
        }
      }
    } else if (valueExpression is IntegerLiteral) {
      return protocol.FlutterWidgetPropertyValue(
        intValue: valueExpression.value,
      );
    } else if (valueExpression is SimpleStringLiteral) {
      return protocol.FlutterWidgetPropertyValue(
        stringValue: valueExpression.value,
      );
    }
    return null;
  }
}
