// Copyright (C) 2014 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.extensions.common;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.gerrit.extensions.client.ChangeStatus;
import com.google.gerrit.extensions.client.ReviewerState;
import com.google.gerrit.extensions.client.SubmitType;
import java.sql.Timestamp;
import java.time.Instant;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * Representation of a change used in the API. Internally {@link
 * com.google.gerrit.server.query.change.ChangeData} and {@link com.google.gerrit.entities.Change}
 * are used.
 *
 * <p>Many fields are actually nullable.
 */
public class ChangeInfo {
  // ActionJson#copy(List, ChangeInfo) must be adapted if new fields are added that are not
  // protected by any ListChangesOption.

  public String id;
  public String tripletId;

  public String project;
  public String branch;
  public String topic;

  /**
   * The <a href="https://www.gerritcodereview.com/design-docs/attention-set.html">attention set</a>
   * for this change. Keyed by account ID. We don't use {@link
   * com.google.gerrit.entities.Account.Id} to avoid a circular dependency.
   */
  public Map<Integer, AttentionSetInfo> attentionSet;

  public Map<Integer, AttentionSetInfo> removedFromAttentionSet;

  public Map<String, String> customKeyedValues;

  public Collection<String> hashtags;
  public String changeId;
  public String subject;
  public ChangeStatus status;

  // TODO(issue-40014498): Migrate timestamp fields in *Info/*Input classes from type Timestamp to
  // Instant
  public Timestamp created;
  public Timestamp updated;
  public Timestamp submitted;

  public AccountInfo submitter;
  public Boolean starred;
  public Collection<String> stars;
  public Boolean reviewed;
  public SubmitType submitType;
  public Boolean mergeable;
  public Boolean submittable;
  public Integer insertions;
  public Integer deletions;
  public Integer totalCommentCount;
  public Integer unresolvedCommentCount;
  public Boolean isPrivate;
  public Boolean workInProgress;
  public Boolean hasReviewStarted;
  public Integer revertOf;
  public String submissionId;
  public Integer cherryPickOfChange;
  public Integer cherryPickOfPatchSet;
  public String metaRevId;

  /**
   * Whether the change contains conflicts.
   *
   * <p>If {@code true}, some of the file contents of the change contain git conflict markers to
   * indicate the conflicts.
   *
   * <p>Only set if this change info is returned in response to a request that creates a new change
   * or patch set and conflicts are allowed. In particular this field is only populated if the
   * change info is returned by one of the following REST endpoints: {@link
   * com.google.gerrit.server.restapi.change.ApplyPatch},{@link
   * com.google.gerrit.server.restapi.change.CreateChange}, {@link
   * com.google.gerrit.server.restapi.change.CreateMergePatchSet}, {@link
   * com.google.gerrit.server.restapi.change.CherryPick}, {@link
   * com.google.gerrit.server.restapi.change.CherryPickCommit}, {@link
   * com.google.gerrit.server.restapi.change.Rebase}
   */
  public Boolean containsGitConflicts;

  public Integer _number;
  public Integer virtualIdNumber;

  public AccountInfo owner;

  public Map<String, ActionInfo> actions;
  public Map<String, LabelInfo> labels;
  public Map<String, Collection<String>> permittedLabels;
  public Map<String, Map<String, List<AccountInfo>>> removableLabels;
  public Collection<AccountInfo> removableReviewers;
  public Map<ReviewerState, Collection<AccountInfo>> reviewers;
  public Map<ReviewerState, Collection<AccountInfo>> pendingReviewers;
  public Collection<ReviewerUpdateInfo> reviewerUpdates;
  public Collection<ChangeMessageInfo> messages;

  public Integer currentRevisionNumber;
  public String currentRevision;
  public Map<String, RevisionInfo> revisions;
  public Boolean _moreChanges;

  public List<ProblemInfo> problems;
  public List<PluginDefinedInfo> plugins;
  public Collection<TrackingIdInfo> trackingIds;
  public Collection<LegacySubmitRequirementInfo> requirements;
  public Collection<SubmitRecordInfo> submitRecords;
  public Collection<SubmitRequirementResultInfo> submitRequirements;

  public ChangeInfo() {}

  public ChangeInfo(ChangeMessageInfo... messages) {
    this.messages = ImmutableList.copyOf(messages);
  }

  public ChangeInfo(Map<String, RevisionInfo> revisions) {
    this.revisions = ImmutableMap.copyOf(revisions);
  }

  // TODO(issue-40014498): Migrate timestamp fields in *Info/*Input classes from type Timestamp to
  // Instant
  @SuppressWarnings("JdkObsolete")
  public Instant getCreated() {
    return created.toInstant();
  }

  // TODO(issue-40014498): Migrate timestamp fields in *Info/*Input classes from type Timestamp to
  // Instant
  @SuppressWarnings("JdkObsolete")
  public void setCreated(Instant when) {
    created = Timestamp.from(when);
  }

  // TODO(issue-40014498): Migrate timestamp fields in *Info/*Input classes from type Timestamp to
  // Instant
  @SuppressWarnings("JdkObsolete")
  public Instant getUpdated() {
    return updated.toInstant();
  }

  // TODO(issue-40014498): Migrate timestamp fields in *Info/*Input classes from type Timestamp to
  // Instant
  @SuppressWarnings("JdkObsolete")
  public void setUpdated(Instant when) {
    updated = Timestamp.from(when);
  }

  // TODO(issue-40014498): Migrate timestamp fields in *Info/*Input classes from type Timestamp to
  // Instant
  @SuppressWarnings("JdkObsolete")
  public Instant getSubmitted() {
    return submitted.toInstant();
  }

  // TODO(issue-40014498): Migrate timestamp fields in *Info/*Input classes from type Timestamp to
  // Instant
  @SuppressWarnings("JdkObsolete")
  public void setSubmitted(Instant when, AccountInfo who) {
    submitted = Timestamp.from(when);
    submitter = who;
  }

  public RevisionInfo getCurrentRevision() {
    RevisionInfo currentRevisionInfo = revisions.get(currentRevision);
    if (currentRevisionInfo.commit != null) {
      // If all revisions are requested the commit.commit field is not populated because the commit
      // SHA1 is already present as the key in the revisions map.
      currentRevisionInfo.commit.commit = currentRevision;
    }
    return currentRevisionInfo;
  }
}
