// 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.entities;

import com.google.auto.value.AutoValue;
import com.google.gerrit.common.Nullable;
import java.time.Instant;
import java.util.Objects;

/**
 * A message attached to a {@link Change}. This message is persisted in data storage, that is why it
 * must have template form that does not contain Gerrit user identifiable information. Hence, it
 * requires processing to convert it to user-facing form.
 *
 * <p>These messages are normally auto-generated by gerrit operations, but might also incorporate
 * user input.
 */
public final class ChangeMessage {

  public static Key key(Change.Id changeId, String uuid) {
    return new AutoValue_ChangeMessage_Key(changeId, uuid);
  }

  @AutoValue
  public abstract static class Key {
    public abstract Change.Id changeId();

    public abstract String uuid();
  }

  private Key key;

  /** Who wrote this comment; null if it was written by the Gerrit system. */
  @Nullable private Account.Id author;

  /** When this comment was drafted. */
  private Instant writtenOn;

  /**
   * The text left by the user or Gerrit system in template form, that is free of Gerrit User
   * Identifiable Information and can be persisted in data storage.
   */
  @Nullable private String message;

  /** Which patchset (if any) was this message generated from? */
  @Nullable private PatchSet.Id patchset;

  /** Tag associated with change message */
  @Nullable private String tag;

  /** Real user that added this message on behalf of the user recorded in {@link #author}. */
  @Nullable private Account.Id realAuthor;

  private ChangeMessage() {}

  public static ChangeMessage create(
      final ChangeMessage.Key k, @Nullable Account.Id a, Instant wo, @Nullable PatchSet.Id psid) {
    return create(k, a, wo, psid, /*messageTemplate=*/ null, /*realAuthor=*/ null, /*tag=*/ null);
  }

  public static ChangeMessage create(
      final ChangeMessage.Key k,
      @Nullable Account.Id a,
      Instant wo,
      @Nullable PatchSet.Id psid,
      @Nullable String messageTemplate,
      @Nullable Account.Id realAuthor,
      @Nullable String tag) {
    ChangeMessage message = new ChangeMessage();
    message.key = k;
    message.author = a;
    message.writtenOn = wo;
    message.patchset = psid;
    message.message = messageTemplate;
    // Use null for same real author, as before the column was added.
    message.realAuthor = Objects.equals(a, realAuthor) ? null : realAuthor;
    message.tag = tag;
    return message;
  }

  public ChangeMessage.Key getKey() {
    return key;
  }

  /** If null, the message was written 'by the Gerrit system'. */
  @Nullable
  public Account.Id getAuthor() {
    return author;
  }

  public Account.Id getRealAuthor() {
    return realAuthor != null ? realAuthor : getAuthor();
  }

  public Instant getWrittenOn() {
    return writtenOn;
  }

  /** Message template, as persisted in data storage. */
  public String getMessage() {
    return message;
  }

  public String getTag() {
    return tag;
  }

  public PatchSet.Id getPatchSetId() {
    return patchset;
  }

  @Override
  public boolean equals(Object o) {
    if (!(o instanceof ChangeMessage)) {
      return false;
    }
    ChangeMessage m = (ChangeMessage) o;
    return Objects.equals(key, m.key)
        && Objects.equals(author, m.author)
        && Objects.equals(writtenOn, m.writtenOn)
        && Objects.equals(message, m.message)
        && Objects.equals(patchset, m.patchset)
        && Objects.equals(tag, m.tag)
        && Objects.equals(realAuthor, m.realAuthor);
  }

  @Override
  public int hashCode() {
    return Objects.hash(key, author, writtenOn, message, patchset, tag, realAuthor);
  }

  @Override
  public String toString() {
    return "ChangeMessage{"
        + "key="
        + key
        + ", author="
        + author
        + ", realAuthor="
        + realAuthor
        + ", writtenOn="
        + writtenOn
        + ", patchset="
        + patchset
        + ", tag="
        + tag
        + ", message=["
        + message
        + "]}";
  }
}
