// Copyright 2012 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.gitiles;

import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Objects.hash;
import static org.eclipse.jgit.lib.Constants.OBJ_BAD;
import static org.eclipse.jgit.lib.Constants.OBJ_TAG;

import com.google.common.annotations.VisibleForTesting;
import java.io.IOException;
import java.util.Objects;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.lib.AbbreviatedObjectId;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.revwalk.RevObject;
import org.eclipse.jgit.revwalk.RevWalk;

/**
 * Object encapsulating a single revision as seen by Gitiles.
 *
 * <p>A single revision consists of a name, an ID, and a type. Name parsing is done once per request
 * by {@link RevisionParser}.
 */
public class Revision {
  /** Sentinel indicating a missing or empty revision. */
  public static final Revision NULL = peeled("", ObjectId.zeroId(), OBJ_BAD);

  /** Common default branch given to clients. */
  public static final Revision HEAD = named("HEAD");

  public static Revision normalizeParentExpressions(Revision rev) {
    if (rev == null || (rev.name.indexOf('~') < 0 && rev.name.indexOf('^') < 0)) {
      return rev;
    }
    return new Revision(rev.id.name(), rev.id, rev.type, rev.peeledId, rev.peeledType);
  }

  private final String name;
  private final ObjectId id;
  private final int type;
  private final ObjectId peeledId;
  private final int peeledType;

  public static Revision peeled(String name, RevObject obj) {
    return peeled(name, obj, obj.getType());
  }

  public static Revision unpeeled(String name, ObjectId id) {
    return peeled(name, id, OBJ_BAD);
  }

  public static Revision named(String name) {
    return peeled(name, null, OBJ_BAD);
  }

  public static Revision peel(String name, RevObject obj, RevWalk walk)
      throws MissingObjectException, IOException {
    RevObject peeled = walk.peel(obj);
    return new Revision(name, obj, obj.getType(), peeled, peeled.getType());
  }

  private static Revision peeled(String name, ObjectId id, int type) {
    checkArgument(type != OBJ_TAG, "expected non-tag for %s/%s", name, id);
    return new Revision(name, id, type, id, type);
  }

  @VisibleForTesting
  Revision(String name, ObjectId id, int type, ObjectId peeledId, int peeledType) {
    this.name = name;
    this.id = id;
    this.type = type;
    this.peeledId = peeledId;
    this.peeledType = peeledType;
  }

  public String getName() {
    return name;
  }

  public int getType() {
    return type;
  }

  public ObjectId getId() {
    return id;
  }

  public ObjectId getPeeledId() {
    return peeledId;
  }

  public int getPeeledType() {
    return peeledType;
  }

  public boolean matches(ObjectId other) {
    return id.equals(other) || nameEqualsAbbreviated(other);
  }

  public boolean nameIsId() {
    return nameEqualsAbbreviated(id);
  }

  @Override
  public boolean equals(Object o) {
    if (o instanceof Revision) {
      Revision r = (Revision) o;
      return Objects.equals(name, r.name)
          && Objects.equals(id, r.id)
          && type == r.type
          && Objects.equals(peeledId, r.peeledId)
          && peeledType == r.peeledType;
    }
    return false;
  }

  @Override
  public int hashCode() {
    return hash(name, id, type, peeledId, peeledType);
  }

  @Override
  public String toString() {
    return toStringHelper(this)
        .omitNullValues()
        .add("name", name)
        .add("id", id != null ? id.getName() : null)
        .add("type", type > 0 ? Constants.typeString(type) : null)
        .add("peeledId", peeledId != null ? peeledId.getName() : null)
        .add("peeledType", type > 0 ? Constants.typeString(peeledType) : null)
        .toString();
  }

  private boolean nameEqualsAbbreviated(ObjectId other) {
    return AbbreviatedObjectId.isId(name)
        && AbbreviatedObjectId.fromString(name).prefixCompare(other) == 0;
  }
}
