// Copyright (C) 2008 The Android Open Source Project
//
// 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.gerrit.reviewdb.client;

import static com.google.gerrit.reviewdb.client.RefNames.REFS_CHANGES;

import com.google.gerrit.extensions.client.ChangeStatus;
import com.google.gwtorm.client.Column;
import com.google.gwtorm.client.IntKey;
import com.google.gwtorm.client.RowVersion;
import com.google.gwtorm.client.StringKey;

import java.sql.Timestamp;
import java.util.Arrays;

/**
 * A change proposed to be merged into a {@link Branch}.
 * <p>
 * The data graph rooted below a Change can be quite complex:
 *
 * <pre>
 *   {@link Change}
 *     |
 *     +- {@link ChangeMessage}: &quot;cover letter&quot; or general comment.
 *     |
 *     +- {@link PatchSet}: a single variant of this change.
 *          |
 *          +- {@link PatchSetApproval}: a +/- vote on the change's current state.
 *          |
 *          +- {@link PatchSetAncestor}: parents of this change's commit.
 *          |
 *          +- {@link PatchLineComment}: comment about a specific line
 * </pre>
 * <p>
 * <h5>PatchSets</h5>
 * <p>
 * Every change has at least one PatchSet. A change starts out with one
 * PatchSet, the initial proposal put forth by the change owner. This
 * {@link Account} is usually also listed as the author and committer in the
 * PatchSetInfo.
 * <p>
 * The {@link PatchSetAncestor} entities are a mirror of the Git commit
 * metadata, providing access to the information without needing direct
 * accessing Git. These entities are actually legacy artifacts from Gerrit 1.x
 * and could be removed, replaced by direct RevCommit access.
 * <p>
 * Each PatchSet contains zero or more Patch records, detailing the file paths
 * impacted by the change (otherwise known as, the file paths the author
 * added/deleted/modified). Sometimes a merge commit can contain zero patches,
 * if the merge has no conflicts, or has no impact other than to cut off a line
 * of development.
 * <p>
 * Each PatchLineComment is a draft or a published comment about a single line
 * of the associated file. These are the inline comment entities created by
 * users as they perform a review.
 * <p>
 * When additional PatchSets appear under a change, these PatchSets reference
 * <i>replacement</i> commits; alternative commits that could be made to the
 * project instead of the original commit referenced by the first PatchSet.
 * <p>
 * A change has at most one current PatchSet. The current PatchSet is updated
 * when a new replacement PatchSet is uploaded. When a change is submitted, the
 * current patch set is what is merged into the destination branch.
 * <p>
 * <h5>ChangeMessage</h5>
 * <p>
 * The ChangeMessage entity is a general free-form comment about the whole
 * change, rather than PatchLineComment's file and line specific context. The
 * ChangeMessage appears at the start of any email generated by Gerrit, and is
 * shown on the change overview page, rather than in a file-specific context.
 * Users often use this entity to describe general remarks about the overall
 * concept proposed by the change.
 * <p>
 * <h5>PatchSetApproval</h5>
 * <p>
 * PatchSetApproval entities exist to fill in the <i>cells</i> of the approvals
 * table in the web UI. That is, a single PatchSetApproval record's key is the
 * tuple {@code (PatchSet,Account,ApprovalCategory)}. Each PatchSetApproval
 * carries with it a small score value, typically within the range -2..+2.
 * <p>
 * If an Account has created only PatchSetApprovals with a score value of 0, the
 * Change shows in their dashboard, and they are said to be CC'd (carbon copied)
 * on the Change, but are not a direct reviewer. This often happens when an
 * account was specified at upload time with the {@code --cc} command line flag,
 * or have published comments, but left the approval scores at 0 ("No Score").
 * <p>
 * If an Account has one or more PatchSetApprovals with a score != 0, the Change
 * shows in their dashboard, and they are said to be an active reviewer. Such
 * individuals are highlighted when notice of a replacement patch set is sent,
 * or when notice of the change submission occurs.
 */
public final class Change {
  public static class Id extends IntKey<com.google.gwtorm.client.Key<?>> {
    private static final long serialVersionUID = 1L;

    @Column(id = 1)
    public int id;

    protected Id() {
    }

    public Id(final int id) {
      this.id = id;
    }

    @Override
    public int get() {
      return id;
    }

    @Override
    protected void set(int newValue) {
      id = newValue;
    }

    /** Parse a Change.Id out of a string representation. */
    public static Id parse(final String str) {
      final Id r = new Id();
      r.fromString(str);
      return r;
    }

    public static Id fromRef(String ref) {
      int cs = startIndex(ref);
      if (cs < 0) {
        return null;
      }
      int ce = nextNonDigit(ref, cs);
      if (ref.substring(ce).equals(RefNames.META_SUFFIX)
          || PatchSet.Id.fromRef(ref, ce) >= 0) {
        return new Change.Id(Integer.parseInt(ref.substring(cs, ce)));
      }
      return null;
    }

    static int startIndex(String ref) {
      if (ref == null || !ref.startsWith(REFS_CHANGES)) {
        return -1;
      }

      // Last 2 digits.
      int ls = REFS_CHANGES.length();
      int le = nextNonDigit(ref, ls);
      if (le - ls != 2 || le >= ref.length() || ref.charAt(le) != '/') {
        return -1;
      }

      // Change ID.
      int cs = le + 1;
      if (cs >= ref.length() || ref.charAt(cs) == '0') {
        return -1;
      }
      int ce = nextNonDigit(ref, cs);
      if (ce >= ref.length() || ref.charAt(ce) != '/') {
        return -1;
      }
      switch (ce - cs) {
        case 0:
          return -1;
        case 1:
          if (ref.charAt(ls) != '0'
              || ref.charAt(ls + 1) != ref.charAt(cs)) {
            return -1;
          }
          break;
        default:
          if (ref.charAt(ls) != ref.charAt(ce - 2)
              || ref.charAt(ls + 1) != ref.charAt(ce - 1)) {
            return -1;
          }
          break;
      }
      return cs;
    }

    static int nextNonDigit(String s, int i) {
      while (i < s.length() && s.charAt(i) >= '0' && s.charAt(i) <= '9') {
        i++;
      }
      return i;
    }
  }

  /** Globally unique identification of this change. */
  public static class Key extends StringKey<com.google.gwtorm.client.Key<?>> {
    private static final long serialVersionUID = 1L;

    @Column(id = 1, length = 60)
    protected String id;

    protected Key() {
    }

    public Key(final String id) {
      this.id = id;
    }

    @Override
    public String get() {
      return id;
    }

    @Override
    protected void set(String newValue) {
      id = newValue;
    }

    /** Construct a key that is after all keys prefixed by this key. */
    public Key max() {
      final StringBuilder revEnd = new StringBuilder(get().length() + 1);
      revEnd.append(get());
      revEnd.append('\u9fa5');
      return new Key(revEnd.toString());
    }

    /** Obtain a shorter version of this key string, using a leading prefix. */
    public String abbreviate() {
      final String s = get();
      return s.substring(0, Math.min(s.length(), 9));
    }

    /** Parse a Change.Key out of a string representation. */
    public static Key parse(final String str) {
      final Key r = new Key();
      r.fromString(str);
      return r;
    }
  }

  /** Minimum database status constant for an open change. */
  private static final char MIN_OPEN = 'a';
  /** Database constant for {@link Status#NEW}. */
  public static final char STATUS_NEW = 'n';
  /** Database constant for {@link Status#SUBMITTED}. */
  public static final char STATUS_SUBMITTED = 's';
  /** Database constant for {@link Status#DRAFT}. */
  public static final char STATUS_DRAFT = 'd';
  /** Maximum database status constant for an open change. */
  private static final char MAX_OPEN = 'z';

  /** Database constant for {@link Status#MERGED}. */
  public static final char STATUS_MERGED = 'M';

  /** ID number of the first patch set in a change. */
  public static final int INITIAL_PATCH_SET_ID = 1;

  /**
   * Current state within the basic workflow of the change.
   *
   * <p>
   * Within the database, lower case codes ('a'..'z') indicate a change that is
   * still open, and that can be modified/refined further, while upper case
   * codes ('A'..'Z') indicate a change that is closed and cannot be further
   * modified.
   * */
  public static enum Status {
    /**
     * Change is open and pending review, or review is in progress.
     *
     * <p>
     * This is the default state assigned to a change when it is first created
     * in the database. A change stays in the NEW state throughout its review
     * cycle, until the change is submitted or abandoned.
     *
     * <p>
     * Changes in the NEW state can be moved to:
     * <ul>
     * <li>{@link #SUBMITTED} - when the Submit Patch Set action is used;
     * <li>{@link #ABANDONED} - when the Abandon action is used.
     * </ul>
     */
    NEW(STATUS_NEW, ChangeStatus.NEW),

    /**
     * Change is open, but has been submitted to the merge queue.
     *
     * <p>
     * A change enters the SUBMITTED state when an authorized user presses the
     * "submit" action through the web UI, requesting that Gerrit merge the
     * change's current patch set into the destination branch.
     *
     * <p>
     * Typically a change resides in the SUBMITTED for only a brief sub-second
     * period while the merge queue fires and the destination branch is updated.
     * However, if a dependency commit (a {@link PatchSetAncestor}, directly or
     * transitively) is not yet merged into the branch, the change will hang in
     * the SUBMITTED state indefinitely.
     *
     * <p>
     * Changes in the SUBMITTED state can be moved to:
     * <ul>
     * <li>{@link #NEW} - when a replacement patch set is supplied, OR when a
     * merge conflict is detected;
     * <li>{@link #MERGED} - when the change has been successfully merged into
     * the destination branch;
     * <li>{@link #ABANDONED} - when the Abandon action is used.
     * </ul>
     */
    SUBMITTED(STATUS_SUBMITTED, ChangeStatus.SUBMITTED),

    /**
     * Change is a draft change that only consists of draft patchsets.
     *
     * <p>
     * This is a change that is not meant to be submitted or reviewed yet. If
     * the uploader publishes the change, it becomes a NEW change.
     * Publishing is a one-way action, a change cannot return to DRAFT status.
     * Draft changes are only visible to the uploader and those explicitly
     * added as reviewers.
     *
     * <p>
     * Changes in the DRAFT state can be moved to:
     * <ul>
     * <li>{@link #NEW} - when the change is published, it becomes a new change;
     * </ul>
     */
    DRAFT(STATUS_DRAFT, ChangeStatus.DRAFT),

    /**
     * Change is closed, and submitted to its destination branch.
     *
     * <p>
     * Once a change has been merged, it cannot be further modified by adding a
     * replacement patch set. Draft comments however may be published,
     * supporting a post-submit review.
     */
    MERGED(STATUS_MERGED, ChangeStatus.MERGED),

    /**
     * Change is closed, but was not submitted to its destination branch.
     *
     * <p>
     * Once a change has been abandoned, it cannot be further modified by adding
     * a replacement patch set, and it cannot be merged. Draft comments however
     * may be published, permitting reviewers to send constructive feedback.
     */
    ABANDONED('A', ChangeStatus.ABANDONED);

    static {
      boolean ok = true;
      if (Status.values().length != ChangeStatus.values().length) {
        ok = false;
      }
      for (Status s : Status.values()) {
        ok &= s.name().equals(s.changeStatus.name());
      }
      if (!ok) {
        throw new IllegalStateException("Mismatched status mapping: "
            + Arrays.asList(Status.values()) + " != "
            + Arrays.asList(ChangeStatus.values()));
      }
    }

    private final char code;
    private final boolean closed;
    private final ChangeStatus changeStatus;

    private Status(char c, ChangeStatus cs) {
      code = c;
      closed = !(MIN_OPEN <= c && c <= MAX_OPEN);
      changeStatus = cs;
    }

    public char getCode() {
      return code;
    }

    public boolean isOpen() {
      return !closed;
    }

    public boolean isClosed() {
      return closed;
    }

    public ChangeStatus asChangeStatus() {
      return changeStatus;
    }

    public static Status forCode(final char c) {
      for (final Status s : Status.values()) {
        if (s.code == c) {
          return s;
        }
      }
      return null;
    }

    public static Status forChangeStatus(ChangeStatus cs) {
      for (Status s : Status.values()) {
        if (s.changeStatus == cs) {
          return s;
        }
      }
      return null;
    }
  }

  /** Locally assigned unique identifier of the change */
  @Column(id = 1)
  protected Id changeId;

  /** Globally assigned unique identifier of the change */
  @Column(id = 2)
  protected Key changeKey;

  /** optimistic locking */
  @Column(id = 3)
  @RowVersion
  protected int rowVersion;

  /** When this change was first introduced into the database. */
  @Column(id = 4)
  protected Timestamp createdOn;

  /**
   * When was a meaningful modification last made to this record's data
   * <p>
   * Note, this update timestamp includes its children.
   */
  @Column(id = 5)
  protected Timestamp lastUpdatedOn;

  // DELETED: id = 6 (sortkey)

  @Column(id = 7, name = "owner_account_id")
  protected Account.Id owner;

  /** The branch (and project) this change merges into. */
  @Column(id = 8)
  protected Branch.NameKey dest;

  // DELETED: id = 9 (open)

  /** Current state code; see {@link Status}. */
  @Column(id = 10)
  protected char status;

  // DELETED: id = 11 (nbrPatchSets)

  /** The current patch set. */
  @Column(id = 12)
  protected int currentPatchSetId;

  /** Subject from the current patch set. */
  @Column(id = 13)
  protected String subject;

  /** Topic name assigned by the user, if any. */
  @Column(id = 14, notNull = false)
  protected String topic;

  // DELETED: id = 15 (lastSha1MergeTested)
  // DELETED: id = 16 (mergeable)

  /**
   * First line of first patch set's commit message.
   *
   * Unlike {@link #subject}, this string does not change if future patch sets
   * change the first line.
   */
  @Column(id = 17, notNull = false)
  protected String originalSubject;

  protected Change() {
  }

  public Change(Change.Key newKey, Change.Id newId, Account.Id ownedBy,
      Branch.NameKey forBranch, Timestamp ts) {
    changeKey = newKey;
    changeId = newId;
    createdOn = ts;
    lastUpdatedOn = createdOn;
    owner = ownedBy;
    dest = forBranch;
    setStatus(Status.NEW);
  }

  public Change(Change other) {
    changeId = other.changeId;
    changeKey = other.changeKey;
    rowVersion = other.rowVersion;
    createdOn = other.createdOn;
    lastUpdatedOn = other.lastUpdatedOn;
    owner = other.owner;
    dest = other.dest;
    status = other.status;
    currentPatchSetId = other.currentPatchSetId;
    subject = other.subject;
    originalSubject = other.originalSubject;
    topic = other.topic;
  }

  /** Legacy 32 bit integer identity for a change. */
  public Change.Id getId() {
    return changeId;
  }

  /** Legacy 32 bit integer identity for a change. */
  public int getChangeId() {
    return changeId.get();
  }

  /** The Change-Id tag out of the initial commit, or a natural key. */
  public Change.Key getKey() {
    return changeKey;
  }

  public void setKey(final Change.Key k) {
    changeKey = k;
  }

  public Timestamp getCreatedOn() {
    return createdOn;
  }

  public Timestamp getLastUpdatedOn() {
    return lastUpdatedOn;
  }

  public void setLastUpdatedOn(Timestamp now) {
    lastUpdatedOn = now;
  }

  public int getRowVersion() {
    return rowVersion;
  }

  public Account.Id getOwner() {
    return owner;
  }

  public Branch.NameKey getDest() {
    return dest;
  }

  public Project.NameKey getProject() {
    return dest.getParentKey();
  }

  public String getSubject() {
    return subject;
  }

  public String getOriginalSubject() {
    return originalSubject != null ? originalSubject : subject;
  }

  /** Get the id of the most current {@link PatchSet} in this change. */
  public PatchSet.Id currentPatchSetId() {
    if (currentPatchSetId > 0) {
      return new PatchSet.Id(changeId, currentPatchSetId);
    }
    return null;
  }

  public void setCurrentPatchSet(final PatchSetInfo ps) {
    if (originalSubject == null && subject != null) {
      // Change was created before schema upgrade. Use the last subject
      // associated with this change, as the most recent discussion will
      // be under that thread in an email client such as GMail.
      originalSubject = subject;
    }

    currentPatchSetId = ps.getKey().get();
    subject = ps.getSubject();

    if (originalSubject == null) {
      // Newly created changes remember the first commit's subject.
      originalSubject = subject;
    }
  }

  public Status getStatus() {
    return Status.forCode(status);
  }

  public void setStatus(Status newStatus) {
    status = newStatus.getCode();
  }

  public String getTopic() {
    return topic;
  }

  public void setTopic(String topic) {
    this.topic = topic;
  }

  @Override
  public String toString() {
    return new StringBuilder(getClass().getSimpleName())
        .append('{').append(changeId)
        .append(" (").append(changeKey).append("), ")
        .append("dest=").append(dest).append(", ")
        .append("status=").append(status).append('}')
        .toString();
  }
}
