// 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.gerrit.common.Nullable;
import java.sql.Timestamp;
import java.util.Objects;

/**
 * Representation of an approval in the REST API.
 *
 * <p>This class determines the JSON format of approvals in the REST API.
 *
 * <p>An approval is a vote of a user for a label on a change.
 */
public class ApprovalInfo extends AccountInfo {
  /**
   * Tag that was set when posting the review that created this approval.
   *
   * <p>Web UIs may use the tag to filter out approvals, e.g. initially hide approvals that have a
   * tag that starts with the {@code autogenerated:} prefix.
   */
  public String tag;

  /**
   * The vote that the user has given for the label.
   *
   * <p>If present and zero, the user is permitted to vote on the label. If absent, the user is not
   * permitted to vote on that label.
   */
  public Integer value;

  /** The time and date describing when the approval was made. */
  public Timestamp date;

  /** Whether this vote was made after the change was submitted. */
  public Boolean postSubmit;

  /**
   * The range the user is authorized to vote on that label.
   *
   * <p>If present, the user is permitted to vote on the label regarding the range values. If
   * absent, the user is not permitted to vote on that label.
   */
  public VotingRangeInfo permittedVotingRange;

  public ApprovalInfo(Integer id) {
    super(id);
  }

  public ApprovalInfo(
      Integer id,
      Integer value,
      @Nullable VotingRangeInfo permittedVotingRange,
      @Nullable String tag,
      Timestamp date) {
    super(id);
    this.value = value;
    this.permittedVotingRange = permittedVotingRange;
    this.date = date;
    this.tag = tag;
  }

  @Override
  public boolean equals(Object o) {
    if (o instanceof ApprovalInfo) {
      ApprovalInfo approvalInfo = (ApprovalInfo) o;
      return super.equals(o)
          && Objects.equals(tag, approvalInfo.tag)
          && Objects.equals(value, approvalInfo.value)
          && Objects.equals(date, approvalInfo.date)
          && Objects.equals(postSubmit, approvalInfo.postSubmit)
          && Objects.equals(permittedVotingRange, approvalInfo.permittedVotingRange);
    }
    return false;
  }

  @Override
  public int hashCode() {
    return Objects.hash(super.hashCode(), tag, value, date, postSubmit, permittedVotingRange);
  }
}
