package com.airbnb.lottie.model;

import android.support.annotation.CheckResult;
import android.support.annotation.Nullable;;
import android.support.annotation.RestrictTo;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Defines which content to target.
 * The keypath can contain wildcards ('*') with match exactly 1 item.
 * or globstars ('**') which match 0 or more items.
 *
 * For example, if your content were arranged like this:
 * Gabriel (Shape Layer)
 *     Body (Shape Group)
 *         Left Hand (Shape)
 *             Fill (Fill)
 *             Transform (Transform)
 *         ...
 * Brandon (Shape Layer)
 *     Body (Shape Group)
 *         Left Hand (Shape)
 *             Fill (Fill)
 *             Transform (Transform)
 *         ...
 *
 *
 * You could:
 *     Match Gabriel left hand fill:
 *        new KeyPath("Gabriel", "Body", "Left Hand", "Fill");
 *     Match Gabriel and Brandon's left hand fill:
 *        new KeyPath("*", "Body", Left Hand", "Fill");
 *     Match anything with the name Fill:
 *        new KeyPath("**", "Fill");
 *
 *
 * NOTE: Content that are part of merge paths or repeaters cannot currently be resolved with
 * a {@link KeyPath}. This may be fixed in the future.
 */
public class KeyPath {

  private final List<String> keys;
  @Nullable private KeyPathElement resolvedElement;

  public KeyPath(String... keys) {
    this.keys = Arrays.asList(keys);
  }

  /**
   * Copy constructor. Copies keys as well.
   */
  private KeyPath(KeyPath keyPath) {
    keys = new ArrayList<>(keyPath.keys);
    resolvedElement = keyPath.resolvedElement;
  }

  /**
   * Returns a new KeyPath with the key added.
   * This is used during keypath resolution. Children normally don't know about all of their parent
   * elements so this is used to keep track of the fully qualified keypath.
   * This returns a key keypath because during resolution, the full keypath element tree is walked
   * and if this modified the original copy, it would remain after popping back up the element tree.
   */
  @CheckResult
  @RestrictTo(RestrictTo.Scope.LIBRARY)
  public KeyPath addKey(String key) {
    KeyPath newKeyPath = new KeyPath(this);
    newKeyPath.keys.add(key);
    return newKeyPath;
  }

  /**
   * Return a new KeyPath with the element resolved to the specified {@link KeyPathElement}.
   */
  @RestrictTo(RestrictTo.Scope.LIBRARY)
  public KeyPath resolve(KeyPathElement element) {
    KeyPath keyPath = new KeyPath(this);
    keyPath.resolvedElement = element;
    return keyPath;
  }

  /**
   * Returns a {@link KeyPathElement} that this has been resolved to. KeyPaths get resolved with
   * resolveKeyPath on LottieDrawable or LottieAnimationView.
   */
  @RestrictTo(RestrictTo.Scope.LIBRARY)
  @Nullable
  public KeyPathElement getResolvedElement() {
    return resolvedElement;
  }

  /**
   * Returns whether they key matches at the specified depth.
   */
  @SuppressWarnings("RedundantIfStatement")
  @RestrictTo(RestrictTo.Scope.LIBRARY)
  public boolean matches(String key, int depth) {
    if (isContainer(key)) {
      // This is an artificial layer we programatically create.
      return true;
    }
    if (depth >= keys.size()) {
      return false;
    }
    if (keys.get(depth).equals(key) ||
        keys.get(depth).equals("**") ||
        keys.get(depth).equals("*")) {
      return true;
    }
    return false;
  }

  /**
   * For a given key and depth, returns how much the depth should be incremented by when
   * resolving a keypath to children.
   *
   * This can be 0 or 2 when there is a globstar and the next key either matches or doesn't match
   * the current key.
   */
  @RestrictTo(RestrictTo.Scope.LIBRARY)
  public int incrementDepthBy(String key, int depth) {
    if (isContainer(key)) {
      // If it's a container then we added programatically and it isn't a part of the keypath.
      return 0;
    }
    if (!keys.get(depth).equals("**")) {
      // If it's not a globstar then it is part of the keypath.
      return 1;
    }
    if (depth == keys.size() - 1) {
      // The last key is a globstar.
      return 0;
    }
    if (keys.get(depth + 1).equals(key)) {
      // We are a globstar and the next key is our current key so consume both.
      return 2;
    }
    return 0;
  }

  /**
   * Returns whether the key at specified depth is fully specific enough to match the full set of
   * keys in this keypath.
   */
  @RestrictTo(RestrictTo.Scope.LIBRARY)
  public boolean fullyResolvesTo(String key, int depth) {
    if (depth >= keys.size()) {
      return false;
    }
    boolean isLastDepth = depth == keys.size() - 1;
    String keyAtDepth = keys.get(depth);
    boolean isGlobstar = keyAtDepth.equals("**");

    if (!isGlobstar) {
      boolean matches = keyAtDepth.equals(key) || keyAtDepth.equals("*");
      return (isLastDepth || (depth == keys.size() - 2 && endsWithGlobstar())) && matches;
    }

    boolean isGlobstarButNextKeyMatches = !isLastDepth && keys.get(depth + 1).equals(key);
    if (isGlobstarButNextKeyMatches) {
      return depth == keys.size() - 2 ||
          (depth == keys.size() - 3 && endsWithGlobstar());
    }

    if (isLastDepth) {
      return true;
    }
    if (depth + 1 < keys.size() - 1) {
      // We are a globstar but there is more than 1 key after the globstar we we can't fully match.
      return false;
    }
    // Return whether the next key (which we now know is the last one) is the same as the current
    // key.
    return keys.get(depth + 1).equals(key);
  }

  /**
   * Returns whether the keypath resolution should propagate to children. Some keypaths resolve
   * to content other than leaf contents (such as a layer or content group transform) so sometimes
   * this will return false.
   */
  @SuppressWarnings("SimplifiableIfStatement")
  @RestrictTo(RestrictTo.Scope.LIBRARY)
  public boolean propagateToChildren(String key, int depth) {
    if ("__container".equals(key)) {
      return true;
    }
    return depth < keys.size() - 1 || keys.get(depth).equals("**");
  }

  /**
   * We artificially create some container groups (like a root ContentGroup for the entire animation
   * and for the contents of a ShapeLayer).
   */
  private boolean isContainer(String key) {
    return "__container".equals(key);
  }

  private boolean endsWithGlobstar() {
    return keys.get(keys.size() - 1).equals("**");
  }

  public String keysToString() {
    return keys.toString();
  }

  @Override public String toString() {
    return "KeyPath{" + "keys=" + keys + ",resolved=" + (resolvedElement != null) + '}';
  }
}
