// 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:dartdoc/src/model/model.dart';
import 'package:dartdoc/src/special_elements.dart';

/// Mixin for subclasses of ModelElement representing Elements that can be
/// inherited from one class to another.
///
/// We can search the inheritance chain between this instance and
/// [definingEnclosingContainer] in [Inheritable.canonicalEnclosingContainer],
/// for the canonical [Class] closest to where this member was defined.  We
/// can then know that when we find [Inheritable.element] inside that [Class]'s
/// namespace, that's the one we should treat as canonical and implementors
/// of this class can use that knowledge to determine canonicalization.
///
/// We pick the class closest to the [definingEnclosingContainer] so that all
/// children of that class inheriting the same member will point to the same
/// place in the documentation, and we pick a canonical class because that's
/// the one in the public namespace that will be documented.
mixin Inheritable on ContainerMember {
  /// True if this [Inheritable] is inherited from a different class.
  bool get isInherited;

  /// True if this [Inheritable] has a parameter whose type is overridden
  /// by a subtype.
  bool get isCovariant;

  @override
  Set<String> get features {
    var _features = super.features;
    if (isOverride) _features.add('override');
    if (isInherited) _features.add('inherited');
    if (isCovariant) _features.add('covariant');
    return _features;
  }

  @override
  Library get canonicalLibrary => canonicalEnclosingContainer?.canonicalLibrary;

  @override
  ModelElement buildCanonicalModelElement() {
    // TODO(jcollins-g): factor out extension logic into [Extendable]
    if (canonicalEnclosingContainer is Extension) {
      return this;
    }
    if (canonicalEnclosingContainer is Class) {
      return (canonicalEnclosingContainer as Class)
          ?.allCanonicalModelElements
          ?.firstWhere(
              (m) =>
                  m.name == name && m.isPropertyAccessor == isPropertyAccessor,
              orElse: () => null);
    }
    if (canonicalEnclosingContainer != null) {
      throw UnimplementedError('${canonicalEnclosingContainer}: unknown type');
    }
    return null;
  }

  @override
  Container computeCanonicalEnclosingContainer() {
    if (isInherited) {
      var searchElement = element.declaration;
      // TODO(jcollins-g): generate warning if an inherited element's definition
      // is in an intermediate non-canonical class in the inheritance chain?
      Class previous;
      Class previousNonSkippable;
      Class found;
      for (var c in inheritance.reversed) {
        // Filter out mixins.
        if (c.containsElement(searchElement)) {
          if ((packageGraph.inheritThrough.contains(previous) &&
                  c != definingEnclosingContainer) ||
              (packageGraph.inheritThrough.contains(c) &&
                  c == definingEnclosingContainer)) {
            return previousNonSkippable
                .memberByExample(this)
                .canonicalEnclosingContainer;
          }
          Class canonicalC =
              packageGraph.findCanonicalModelElementFor(c.element);
          // TODO(jcollins-g): invert this lookup so traversal is recursive
          // starting from the ModelElement.
          if (canonicalC != null) {
            assert(canonicalC.isCanonical);
            assert(canonicalC.containsElement(searchElement));
            found = canonicalC;
            break;
          }
        }
        previous = c;
        if (!packageGraph.inheritThrough.contains(c)) {
          previousNonSkippable = c;
        }
      }
      // This is still OK because we're never supposed to cloak public
      // classes.
      if (definingEnclosingContainer.isCanonical &&
          definingEnclosingContainer.isPublic) {
        assert(definingEnclosingContainer == found);
      }
      if (found != null) {
        return found;
      }
    } else if (!isInherited && definingEnclosingContainer is! Extension) {
      // TODO(jcollins-g): factor out extension logic into [Extendable].
      return packageGraph
          .findCanonicalModelElementFor(element.enclosingElement);
    }
    return super.computeCanonicalEnclosingContainer();
  }

  List<Class> get inheritance {
    var inheritance = <Class>[];
    inheritance.addAll((enclosingElement as Class).inheritanceChain);
    var object = packageGraph.specialClasses[SpecialClass.object];
    if (!inheritance.contains(definingEnclosingContainer) &&
        definingEnclosingContainer != null) {
      assert(definingEnclosingContainer == object);
    }
    // Unless the code explicitly extends dart-core's Object, we won't get
    // an entry here.  So add it.
    if (inheritance.last != object && object != null) {
      inheritance.add(object);
    }
    assert(inheritance.where((e) => e == object).length == 1);
    return inheritance;
  }

  Inheritable get overriddenElement;

  bool _isOverride;

  /// True if this [Inheritable] is overriding a superclass.
  bool get isOverride {
    if (_isOverride == null) {
      // The canonical version of the enclosing element -- not canonicalEnclosingElement,
      // as that is the element enclosing the canonical version of this element,
      // two different things.  Defaults to the enclosing element.
      //
      // We use canonical elements here where possible to deal with reexports
      // as seen in Flutter.
      if (enclosingElement is Extension) {
        _isOverride = false;
        return _isOverride;
      }
      Class enclosingCanonical = enclosingElement.canonicalModelElement;
      // The container in which this element was defined, canonical if available.
      Container definingCanonical =
          definingEnclosingContainer.canonicalModelElement ??
              definingEnclosingContainer;
      // The canonical version of the element we're overriding, if available.
      var overriddenCanonical =
          overriddenElement?.canonicalModelElement ?? overriddenElement;

      // We have to have an overridden element for it to be possible for this
      // element to be an override.
      _isOverride = overriddenElement != null &&
          // The defining class and the enclosing class for this element
          // must be the same (element is defined here).
          enclosingCanonical == definingCanonical &&
          // If the overridden element isn't public, we shouldn't be an
          // override in most cases.  Approximation until #1623 is fixed.
          overriddenCanonical.isPublic;
      assert(!(_isOverride && isInherited));
    }
    return _isOverride;
  }

  int _overriddenDepth;

  @override
  int get overriddenDepth {
    if (_overriddenDepth == null) {
      _overriddenDepth = 0;
      var e = this;
      while (e.overriddenElement != null) {
        _overriddenDepth += 1;
        e = e.overriddenElement;
      }
    }
    return _overriddenDepth;
  }
}
