// Copyright (c) 2024, 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:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/utilities/extensions/string.dart';
import 'package:collection/collection.dart';

const String widgetsUri = 'package:flutter/widgets.dart';
const _nameAlign = 'Align';
const _nameBuildContext = 'BuildContext';
const _nameBuilder = 'Builder';
const _nameCenter = 'Center';
const _nameContainer = 'Container';
const _nameExpanded = 'Expanded';
const _nameFlex = 'Flex';
const _nameFlexible = 'Flexible';
const _namePadding = 'Padding';
const _nameSizedBox = 'SizedBox';
const _nameState = 'State';
const _nameStatefulWidget = 'StatefulWidget';
const _nameStatelessWidget = 'StatelessWidget';

const _nameWidget = 'Widget';
final Uri _uriAlignment = Uri.parse(
  'package:flutter/src/painting/alignment.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 _uriDiagnostics = Uri.parse(
  'package:flutter/src/foundation/diagnostics.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');

extension AstNodeExtension on AstNode? {
  /// Returns the instance creation expression that surrounds this node, if any,
  /// and otherwise `null`.
  ///
  /// This node may be the instance creation expression itself or an (optionally
  /// prefixed) identifier that names the constructor.
  InstanceCreationExpression? get findInstanceCreationExpression {
    var node = this;
    if (node is ImportPrefixReference) {
      node = node.parent;
    }
    if (node is SimpleIdentifier) {
      node = node.parent;
    }
    if (node is PrefixedIdentifier) {
      node = node.parent;
    }
    if (node is NamedType) {
      node = node.parent;
    }
    if (node is ConstructorName) {
      node = node.parent;
    }
    if (node is InstanceCreationExpression) {
      return node;
    }
    return null;
  }

  /// Attempts to find and return the closest expression that encloses this
  /// and is an independent Flutter `Widget`.
  ///
  /// Returns `null` if nothing is found.
  Expression? get findWidgetExpression {
    for (var node = this; node != null; node = node.parent) {
      if (!node.isWidgetExpression) {
        if (node is ArgumentList || node is Statement || node is FunctionBody) {
          return null;
        }
        continue;
      }

      if (node is AssignmentExpression) {
        return null;
      }

      var parent = node.parent;

      if (parent is AssignmentExpression) {
        if (parent.rightHandSide == node) {
          return node as Expression;
        }
        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 ||
          parent is SwitchExpressionCase && parent.expression == node ||
          parent is VariableDeclaration) {
        return node as Expression;
      }
    }
    return null;
  }

  /// Whether this [AstNode] is the Flutter class `Widget`, or its subtype.
  bool get isWidgetExpression {
    return switch (this) {
      null => false,
      AstNode(parent: NamedType()) ||
      AstNode(parent: AstNode(parent: NamedType())) => false,
      AstNode(parent: ConstructorName()) => false,
      NamedExpression() => false,
      Expression(:var staticType) => staticType.isWidgetType,
      _ => false,
    };
  }

  /// Finds the named expression whose name is the given [name] that is an
  /// argument to a Flutter instance creation expression.
  ///
  /// Returns `null` if this is not a [SimpleIdentifier], or if any other
  /// condition cannot be satisfied.
  NamedExpression? findArgumentNamed(String name) {
    var self = this;
    if (self is! SimpleIdentifier) {
      return null;
    }
    var parent = self.parent;
    var grandParent = parent?.parent;
    if (parent is Label && grandParent is NamedExpression) {
      if (self.name != name) {
        return null;
      }
    } else {
      return null;
    }
    var invocation = grandParent.parent?.parent;
    if (invocation is! InstanceCreationExpression ||
        !invocation.isWidgetCreation) {
      return null;
    }
    return grandParent;
  }
}

extension ClassElementExtension2 on ClassElement {
  /// Whether this is the Flutter class `State`.
  bool get isExactState => _isExactly(_nameState, _uriFramework);

  /// Whether this has the Flutter class `State` as a superclass.
  bool get isState => _hasSupertype(_uriFramework, _nameState);

  /// Whether this is a [ClassElement] that extends the Flutter class
  /// `StatefulWidget`.
  bool get isStatefulWidgetDeclaration => supertype.isExactlyStatefulWidgetType;
}

extension DartTypeExtension on DartType? {
  /// Whether this is the Flutter type `BuildContext`.
  bool get isBuildContext {
    var self = this;
    return self is InterfaceType &&
        self.nullabilitySuffix == NullabilitySuffix.none &&
        self.element3._isExactly(_nameBuildContext, _uriFramework);
  }

  /// Whether this is the 'dart.ui' class `Color`, or a subtype.
  bool get isColor {
    var self = this;
    if (self is! InterfaceType) {
      return false;
    }

    return [self, ...self.element3.allSupertypes].any(
      (t) =>
          t.element3.name3 == 'Color' && t.element3.library2.name3 == 'dart.ui',
    );
  }

  /// Whether this is the Flutter mixin `Diagnosticable` or a subtype.
  bool get isDiagnosticable {
    var self = this;
    if (self is! InterfaceType) {
      return false;
    }

    return [self, ...self.element3.allSupertypes].any(
      (t) =>
          t.element3.name3 == 'Diagnosticable' &&
          t.element3.library2.firstFragment.source.uri == _uriDiagnostics,
    );
  }

  /// Whether this is the Flutter type `EdgeInsetsGeometry`.
  bool get isExactEdgeInsetsGeometryType {
    var self = this;
    return self is InterfaceType &&
        self.element3._isExactly('EdgeInsetsGeometry', _uriEdgeInsets);
  }

  /// Whether this is the Flutter class `StatefulWidget`.
  bool get isExactlyStatefulWidgetType {
    var self = this;
    return self is InterfaceType &&
        self.element3._isExactly(_nameStatefulWidget, _uriFramework);
  }

  /// Whether this is the Flutter class `StatelessWidget`.
  bool get isExactlyStatelessWidgetType {
    var self = this;
    return self is InterfaceType &&
        self.element3._isExactly(_nameStatelessWidget, _uriFramework);
  }

  /// Whether this is the Flutter class `Align`.
  bool get isExactWidgetTypeAlign {
    var self = this;
    return self is InterfaceType &&
        self.element3._isExactly(_nameAlign, _uriBasic);
  }

  /// Whether this is the Flutter class `Builder`.
  bool get isExactWidgetTypeBuilder {
    var self = this;
    return self is InterfaceType &&
        self.element3._isExactly(_nameBuilder, _uriBasic);
  }

  /// Whether this is the Flutter class `Center`.
  bool get isExactWidgetTypeCenter {
    var self = this;
    return self is InterfaceType &&
        self.element3._isExactly(_nameCenter, _uriBasic);
  }

  /// Whether this is the Flutter class `Container`.
  bool get isExactWidgetTypeContainer {
    var self = this;
    return self is InterfaceType &&
        self.element3._isExactly(_nameContainer, _uriContainer);
  }

  /// Whether this is the Flutter class `Expanded`.
  bool get isExactWidgetTypeExpanded {
    var self = this;
    return self is InterfaceType &&
        self.element3._isExactly(_nameExpanded, _uriBasic);
  }

  /// Whether this is the Flutter class `Flexible`.
  bool get isExactWidgetTypeFlexible {
    var self = this;
    return self is InterfaceType &&
        self.element3._isExactly(_nameFlexible, _uriBasic);
  }

  /// Whether this is the Flutter class `Padding`.
  bool get isExactWidgetTypePadding {
    var self = this;
    return self is InterfaceType &&
        self.element3._isExactly(_namePadding, _uriBasic);
  }

  /// Whether this is the Flutter class `SizedBox`.
  bool get isExactWidgetTypeSizedBox {
    var self = this;
    return self is InterfaceType &&
        self.element3._isExactly(_nameSizedBox, _uriBasic);
  }

  /// Whether this is the Flutter class `Widget`, or its subtype.
  bool get isListOfWidgetsType {
    var self = this;
    return self is InterfaceType &&
        self.isDartCoreList &&
        self.typeArguments[0].isWidgetType;
  }

  /// Whether this is the vector_math_64 class `Matrix4`, or its
  /// subtype.
  bool get isMatrix4 {
    var self = this;
    if (self is! InterfaceType) {
      return false;
    }

    return [self, ...self.element3.allSupertypes].any(
      (t) =>
          t.element3.name3 == 'Matrix4' &&
          t.element3.library2.name3 == 'vector_math_64',
    );
  }

  /// Whether this is a function type matching the Flutter typedef
  /// `WidgetBuilder` (i.e., `Widget Function(BuildContext context)`).
  bool get isWidgetBuilder {
    var self = this;
    return self is FunctionType &&
        self.returnType.isWidgetType &&
        self.formalParameters.length == 1 &&
        self.formalParameters[0].type.isBuildContext;
  }

  /// Whether this is the Flutter class `Widget`, or its subtype.
  bool get isWidgetType {
    var self = this;
    return self is InterfaceType && self.element3.isWidget;
  }
}

extension ElementAnnotationExtension on ElementAnnotation {
  static final Uri _flutterWidgetPreviewLibraryUri = Uri.parse(
    'package:flutter/src/widget_previews/widget_previews.dart',
  );

  /// Whether the annotation marks the associated member as being a widget
  /// preview.
  bool get isWidgetPreview {
    var element2 = this.element2;
    if (element2 is! ConstructorElement) {
      return false;
    }
    return element2.enclosingElement.name3 == 'Preview' &&
        element2.library2.uri == _flutterWidgetPreviewLibraryUri;
  }
}

extension ExpressionExtension on Expression {
  /// Whether this is the `builder` argument.
  bool get isBuilderArgument {
    var self = this;
    return self is NamedExpression && self.name.label.name == 'builder';
  }

  /// Whether this is the `child` argument.
  bool get isChildArgument {
    var self = this;
    return self is NamedExpression && self.name.label.name == 'child';
  }

  /// Whether this is the `children` argument.
  bool get isChildrenArgument {
    var self = this;
    return self is NamedExpression && self.name.label.name == 'children';
  }

  /// Whether this is the `sliver` argument.
  bool get isSliverArgument {
    var self = this;
    return self is NamedExpression && self.name.label.name == 'sliver';
  }

  /// Whether this is the `slivers` argument.
  bool get isSliversArgument {
    var self = this;
    return self is NamedExpression && self.name.label.name == 'slivers';
  }
}

extension InstanceCreationExpressionExtension on InstanceCreationExpression {
  /// The named expression representing the `builder` argument, or `null` if
  /// there is none.
  NamedExpression? get builderArgument => argumentList.arguments
      .whereType<NamedExpression>()
      .firstWhereOrNull((argument) => argument.isBuilderArgument);

  /// The named expression representing the `child` argument, or `null` if there
  /// is none.
  NamedExpression? get childArgument => argumentList.arguments
      .whereType<NamedExpression>()
      .firstWhereOrNull((argument) => argument.isChildArgument);

  /// The named expression representing the `children` argument, or `null` if
  /// there is none.
  NamedExpression? get childrenArgument => argumentList.arguments
      .whereType<NamedExpression>()
      .firstWhereOrNull((argument) => argument.isChildrenArgument);

  bool get isExactlyAlignCreation => staticType.isExactWidgetTypeAlign;

  bool get isExactlyContainerCreation => staticType.isExactWidgetTypeContainer;

  bool get isExactlyPaddingCreation => staticType.isExactWidgetTypePadding;

  /// Whether this is a constructor invocation for a class that has the Flutter
  /// class `Widget` as a superclass.
  bool get isWidgetCreation {
    var element = constructorName.element?.enclosingElement;
    return element.isWidget;
  }

  /// The named expression representing the `sliver` argument, or `null` if there
  /// is none.
  NamedExpression? get sliverArgument => argumentList.arguments
      .whereType<NamedExpression>()
      .firstWhereOrNull((argument) => argument.isSliverArgument);

  /// The named expression representing the `slivers` argument, or `null` if
  /// there is none.
  NamedExpression? get sliversArgument => argumentList.arguments
      .whereType<NamedExpression>()
      .firstWhereOrNull((argument) => argument.isSliversArgument);

  /// The presentation for this node.
  String? get widgetPresentationText {
    var element = constructorName.element?.enclosingElement;
    if (!element.isWidget) {
      return null;
    }
    var arguments = argumentList.arguments;
    if (element._isExactly('Icon', _uriWidgetsIcon)) {
      if (arguments.isNotEmpty) {
        var text = arguments[0].toString();
        var arg = text.elideTo(32);
        return 'Icon($arg)';
      } else {
        return 'Icon';
      }
    }
    if (element._isExactly('Text', _uriWidgetsText)) {
      if (arguments.isNotEmpty) {
        var text = arguments[0].toString();
        var arg = text.elideTo(32);
        return 'Text($arg)';
      } else {
        return 'Text';
      }
    }
    return element?.name3;
  }
}

extension InterfaceElement2Extension on InterfaceElement? {
  /// Whether this is the Flutter class `Flex`, or a subtype.
  bool get isFlexWidget {
    var self = this;
    if (self is! ClassElement) {
      return false;
    }
    if (!self.isWidget) {
      return false;
    }
    if (_isExactly(_nameFlex, _uriBasic)) {
      return true;
    }
    return self.allSupertypes.any(
      (type) => type.element3._isExactly(_nameFlex, _uriBasic),
    );
  }
}

extension InterfaceElementExtension2 on InterfaceElement? {
  /// Whether this is the Flutter class `Alignment`.
  bool get isExactAlignment {
    return _isExactly('Alignment', _uriAlignment);
  }

  /// Whether this is the Flutter class `AlignmentDirectional`.
  bool get isExactAlignmentDirectional {
    return _isExactly('AlignmentDirectional', _uriAlignment);
  }

  /// Whether this is the Flutter class `AlignmentGeometry`.
  bool get isExactAlignmentGeometry {
    return _isExactly('AlignmentGeometry', _uriAlignment);
  }

  /// Whether this is the Flutter class `Widget`, or a subtype.
  bool get isWidget {
    var self = this;
    if (self is! ClassElement) {
      return false;
    }
    if (_isExactly(_nameWidget, _uriFramework)) {
      return true;
    }
    return self.allSupertypes.any(
      (type) => type.element3._isExactly(_nameWidget, _uriFramework),
    );
  }

  /// Whether this has a supertype with the [requiredName] defined in the file
  /// with the [requiredUri].
  bool _hasSupertype(Uri requiredUri, String requiredName) {
    var self = this;
    if (self == null) {
      return false;
    }
    for (var type in self.allSupertypes) {
      if (type.element3.name3 == requiredName) {
        var uri = type.element3.library2.firstFragment.source.uri;
        if (uri == requiredUri) {
          return true;
        }
      }
    }
    return false;
  }

  /// Whether this is the exact [type] defined in the file with the given [uri].
  bool _isExactly(String type, Uri uri) {
    var self = this;
    return self is ClassElement &&
        self.name3 == type &&
        self.firstFragment.libraryFragment.source.uri == uri;
  }
}

extension NamedTypeExtension on NamedType {
  /// Whether this type is a valid return type for a function annotated with
  /// `@Preview(...)`.
  ///
  /// Valid widget preview return types are:
  ///   - `Widget`
  ///   - `Widget Function(BuildContext)` (aka `WidgetBuilder`)
  bool get isValidWidgetPreviewReturnType {
    var self = this;
    return self.type.isWidgetType || self.type.isWidgetBuilder;
  }
}
