// 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 'dart:convert';

import 'package:analyzer/dart/ast/ast.dart'
    show Expression, InstanceCreationExpression;
import 'package:analyzer/dart/element/element2.dart' show Annotatable;
import 'package:analyzer/source/line_info.dart';
// ignore: implementation_imports
import 'package:analyzer/src/dart/element/element.dart'
    show ConstVariableElement;
import 'package:dartdoc/src/element_type.dart';
import 'package:dartdoc/src/model/accessor.dart';
import 'package:dartdoc/src/model/annotation.dart';
import 'package:dartdoc/src/model/attribute.dart';
import 'package:dartdoc/src/model/class.dart';
import 'package:dartdoc/src/model/comment_referable.dart';
import 'package:dartdoc/src/model/constructor.dart';
import 'package:dartdoc/src/model/documentation_comment.dart';
import 'package:dartdoc/src/model/enum.dart';
import 'package:dartdoc/src/model/model_element.dart';
import 'package:dartdoc/src/model/parameter.dart';
import 'package:dartdoc/src/utils.dart';
import 'package:meta/meta.dart';

/// Mixin for top-level variables and fields (aka properties).
mixin GetterSetterCombo on ModelElement {
  Accessor? get getter;

  Accessor? get setter;

  @override
  List<Annotation> get annotations => [
        ...super.annotations,
        if (hasGetter) ...getter!.annotations,
        if (hasSetter) ...setter!.annotations,
      ];

  List<Accessor> get allAccessors {
    final getter = this.getter;
    final setter = this.setter;
    if (getter == null) {
      return setter == null ? const [] : [setter];
    } else {
      return setter == null ? [getter] : [getter, setter];
    }
  }

  @protected
  Set<Attribute> get comboAttributes => {
        if (hasExplicitGetter && hasPublicGetter) ...getter!.attributes,
        if (hasExplicitSetter && hasPublicSetter) ...setter!.attributes,
        if (readOnly && !isFinal && !isConst) Attribute.noSetter,
        if (writeOnly) Attribute.noGetter,
        if (readWrite && !isLate) Attribute.getterSetterPair,
      };

  @override
  ModelElement get enclosingElement;

  bool get isInherited;

  @override
  // Food for mustachio; because this is a mixin, mustachio can't figure out
  // that this implicitly has a `name` property.
  String get name;

  @override
  String get fileName => isConst
      ? '$name-constant.html'
      : name == 'index'
          ? '$name-property.html'
          : '$name.html';

  /// Whether this has a constant value which should be displayed.
  bool get hasConstantValueForDisplay => false;

  late final Expression? _constantInitializer =
      (element2.firstFragment as ConstVariableElement).constantInitializer;

  String linkifyConstantValue(String original) {
    if (_constantInitializer is! InstanceCreationExpression) return original;

    var element = _constantInitializer.constructorName.element;
    if (element == null) return original;

    var target = getModelForElement2(element) as Constructor;
    var enclosingElement = target.enclosingElement;
    if (enclosingElement is! Class) return original;

    // TODO(jcollins-g): this logic really should be integrated into
    // `Constructor`, but that's not trivial because of `linkedName`'s usage.
    if (target.isUnnamedConstructor) {
      var parts = target.linkedNameParts;
      // We don't want the `.new` representation of an unnamed constructor.
      var linkedName = '${parts.tag}${enclosingElement.name}${parts.endTag}';
      return original.replaceAll(enclosingElement.name, linkedName);
    }
    return original.replaceAll('${enclosingElement.name}.${target.name}',
        '${enclosingElement.linkedName}.${target.linkedName}');
  }

  @override
  CharacterLocation? get characterLocation {
    if (enclosingElement is Enum) {
      if (name == 'values') {
        return null;
      } else if (name == 'index') {
        return null;
      }
    }
    // Handle all synthetic possibilities.  Ordinarily, warnings for
    // explicit setters/getters will be handled by those objects, but
    // if a warning comes up for an enclosing synthetic field we have to
    // put it somewhere.  So pick an accessor.
    if (element2.isSynthetic) {
      if (hasExplicitGetter) return getter!.characterLocation;
      if (hasExplicitSetter) return setter!.characterLocation;
      assert(false, 'Field and accessors can not all be synthetic: $element2');
    }
    return super.characterLocation;
  }

  String get constantValue => linkifyConstantValue(constantValueBase);

  String get constantValueTruncated =>
      linkifyConstantValue(truncateString(constantValueBase, 200));

  /// The base text for this property's constant value as an unlinked String.
  late final String constantValueBase = () {
    if (_constantInitializer == null) {
      return '';
    }

    var initializerString = _constantInitializer.toString();

    final self = this;
    if (self is! EnumField ||
        _constantInitializer is! InstanceCreationExpression) {
      return _htmlEscape.convert(initializerString);
    }

    initializerString = 'const $initializerString';

    var isImplicitConstructorCall =
        _constantInitializer.constructorName.element?.isDefaultConstructor ??
            false;
    if (isImplicitConstructorCall) {
      // For an enum value with an implicit constructor call (like
      // `enum E { one, two; }`), `constantInitializer.toString()` does not
      // include the implicit enum index argument (it is something like
      // `const E()`). We must manually include it. See
      // https://github.com/dart-lang/sdk/issues/54988.
      initializerString =
          initializerString.replaceFirst('()', '(${self.index})');
    }
    return _htmlEscape.convert(initializerString);
  }();

  static const _htmlEscape = HtmlEscape(HtmlEscapeMode.unknown);

  late final bool hasPublicGetter = hasGetter && getter!.isPublic;

  late final bool hasPublicSetter = hasSetter && setter!.isPublic;

  @override
  bool get isPublic => hasPublicGetter || hasPublicSetter;

  @override
  late final List<DocumentationComment> documentationFrom = () {
    var comments = [
      if (hasPublicGetter)
        ...getter!.documentationFrom
      else if (hasPublicSetter)
        ...setter!.documentationFrom,
    ];
    return (comments.isEmpty ||
            comments.every((e) => e.documentationComment == ''))
        ? super.documentationFrom
        : comments;
  }();

  bool get hasAccessorsWithDocs =>
      hasPublicGetter && !getter!.isSynthetic && getter!.hasDocumentation ||
      hasPublicSetter && !setter!.isSynthetic && setter!.hasDocumentation;

  bool get getterSetterBothAvailable =>
      hasPublicGetter &&
      getter!.hasDocumentation &&
      hasPublicSetter &&
      setter!.hasDocumentation;

  @override
  late final String oneLineDoc = () {
    if (!hasAccessorsWithDocs) {
      return super.oneLineDoc;
    } else {
      var buffer = StringBuffer();
      if (hasPublicGetter && getter!.oneLineDoc.isNotEmpty) {
        buffer.write(getter!.oneLineDoc);
      }
      if (hasPublicSetter &&
          setter!.oneLineDoc.isNotEmpty &&
          !getterSetterBothAvailable) {
        buffer.write(setter!.oneLineDoc);
      }
      return buffer.toString();
    }
  }();

  @override
  late final String documentationComment =
      _getterSetterDocumentationComment.isEmpty
          ? (element2 as Annotatable).documentationComment ?? ''
          : _getterSetterDocumentationComment;

  @override
  bool get hasDocumentationComment =>
      _getterSetterDocumentationComment.isNotEmpty ||
      (element2 as Annotatable).documentationComment != null;

  /// Derives a documentation comment for the combo by copying documentation
  /// from the [getter] and/or [setter].
  late final String _getterSetterDocumentationComment = () {
    // Check for synthetic before public, always, or stack overflow.
    var getterComment = '';
    if (hasGetter) {
      final getter = this.getter!;
      if (!getter.isSynthetic && getter.isPublic) {
        assert(getter.documentationFrom.length == 1);
        var fromGetter = getter.documentationFrom.first;
        if (fromGetter.hasDocumentationComment) {
          getterComment = fromGetter.documentationComment;
        }
      }
    }

    if (!hasSetter) {
      return getterComment;
    }

    final setter = this.setter!;
    if (setter.isSynthetic || !setter.isPublic) return getterComment;

    assert(setter.documentationFrom.length == 1);
    var fromSetter = setter.documentationFrom.first;
    if (fromSetter.hasDocumentationComment) {
      return getterComment.isEmpty
          ? fromSetter.documentationComment
          : '$getterComment\n\n${fromSetter.documentationComment}';
    } else {
      return getterComment;
    }
  }();

  ElementType get modelType {
    if (hasGetter) return getter!.modelType.returnType;
    return setter!.parameters.first.modelType;
  }

  @override
  bool get isCallable => hasSetter;

  @override
  bool get hasParameters => hasSetter;

  @override
  List<Parameter> get parameters => setter!.parameters;

  @override
  String? get linkedParamsNoMetadata => setter?.linkedParamsNoMetadata;

  bool get hasExplicitGetter => hasPublicGetter && !getter!.isSynthetic;

  bool get hasExplicitSetter => hasPublicSetter && !setter!.isSynthetic;

  bool get hasGetter => getter != null;

  bool get hasGetterOrSetter => hasExplicitGetter || hasExplicitSetter;

  bool get hasSetter => setter != null;

  bool get hasPublicGetterNoSetter => hasPublicGetter && !hasPublicSetter;

  String get arrow {
    // →
    if (readOnly) return r'&#8594;';
    // ←
    if (writeOnly) return r'&#8592;';
    // ↔
    if (readWrite) return r'&#8596;';
    throw UnsupportedError(
        'GetterSetterCombo must be one of readOnly, writeOnly, or readWrite');
  }

  // TODO(srawlins): This should be private.
  bool get readOnly => hasPublicGetter && !hasPublicSetter;

  // TODO(srawlins): This should be private.
  bool get readWrite => hasPublicGetter && hasPublicSetter;

  // TODO(srawlins): This should be private.
  bool get writeOnly => hasPublicSetter && !hasPublicGetter;

  @override
  late final Map<String, CommentReferable> referenceChildren = {
    if (hasParameters) ...parameters.explicitOnCollisionWith(this),
    ...modelType.typeArguments.explicitOnCollisionWith(this),
  };
}
