// 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 com.google.gerrit.common.Nullable;
import com.google.gerrit.extensions.client.Comment.Range;
import com.google.gwtorm.client.StringKey;
import java.sql.Timestamp;
import java.util.Objects;

/**
 * A comment left by a user on a specific line of a {@link Patch}.
 *
 * <p>New APIs should not expose this class.
 *
 * @see Comment
 */
public final class PatchLineComment {
  public static class Key extends StringKey<Patch.Key> {
    private static final long serialVersionUID = 1L;

    public static Key from(Change.Id changeId, Comment.Key key) {
      return new Key(
          new Patch.Key(new PatchSet.Id(changeId, key.patchSetId), key.filename), key.uuid);
    }

    protected Patch.Key patchKey;

    protected String uuid;

    protected Key() {
      patchKey = new Patch.Key();
    }

    public Key(Patch.Key p, String uuid) {
      this.patchKey = p;
      this.uuid = uuid;
    }

    @Override
    public Patch.Key getParentKey() {
      return patchKey;
    }

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

    @Override
    public void set(String newValue) {
      uuid = newValue;
    }

    public Comment.Key asCommentKey() {
      return new Comment.Key(
          get(), getParentKey().getFileName(), getParentKey().getParentKey().get());
    }
  }

  public static final char STATUS_DRAFT = 'd';
  public static final char STATUS_PUBLISHED = 'P';

  public enum Status {
    DRAFT(STATUS_DRAFT),

    PUBLISHED(STATUS_PUBLISHED);

    private final char code;

    Status(char c) {
      code = c;
    }

    public char getCode() {
      return code;
    }

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

  public static PatchLineComment from(
      Change.Id changeId, PatchLineComment.Status status, Comment c) {
    PatchLineComment.Key key =
        new PatchLineComment.Key(
            new Patch.Key(new PatchSet.Id(changeId, c.key.patchSetId), c.key.filename), c.key.uuid);

    PatchLineComment plc =
        new PatchLineComment(key, c.lineNbr, c.author.getId(), c.parentUuid, c.writtenOn);
    plc.setSide(c.side);
    plc.setMessage(c.message);
    if (c.range != null) {
      Comment.Range r = c.range;
      plc.setRange(new CommentRange(r.startLine, r.startChar, r.endLine, r.endChar));
    }
    plc.setTag(c.tag);
    plc.setRevId(new RevId(c.revId));
    plc.setStatus(status);
    plc.setRealAuthor(c.getRealAuthor().getId());
    plc.setUnresolved(c.unresolved);
    return plc;
  }

  protected Key key;

  /** Line number this comment applies to; it should display after the line. */
  protected int lineNbr;

  /** Who wrote this comment. */
  protected Account.Id author;

  /** When this comment was drafted. */
  protected Timestamp writtenOn;

  /** Current publication state of the comment; see {@link Status}. */
  protected char status;

  /** Which file is this comment; 0 is ancestor, 1 is new version. */
  protected short side;

  /** The text left by the user. */
  @Nullable protected String message;

  /** The parent of this comment, or null if this is the first comment on this line */
  @Nullable protected String parentUuid;

  @Nullable protected CommentRange range;

  @Nullable protected String tag;

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

  /** True if this comment requires further action. */
  protected boolean unresolved;

  /** The RevId for the commit to which this comment is referring. */
  protected RevId revId;

  protected PatchLineComment() {}

  public PatchLineComment(
      PatchLineComment.Key id, int line, Account.Id a, String parentUuid, Timestamp when) {
    key = id;
    lineNbr = line;
    author = a;
    setParentUuid(parentUuid);
    setStatus(Status.DRAFT);
    setWrittenOn(when);
  }

  public PatchLineComment(PatchLineComment o) {
    key = o.key;
    lineNbr = o.lineNbr;
    author = o.author;
    realAuthor = o.realAuthor;
    writtenOn = o.writtenOn;
    status = o.status;
    side = o.side;
    message = o.message;
    parentUuid = o.parentUuid;
    revId = o.revId;
    if (o.range != null) {
      range =
          new CommentRange(
              o.range.getStartLine(),
              o.range.getStartCharacter(),
              o.range.getEndLine(),
              o.range.getEndCharacter());
    }
  }

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

  public PatchSet.Id getPatchSetId() {
    return key.getParentKey().getParentKey();
  }

  public int getLine() {
    return lineNbr;
  }

  public void setLine(int line) {
    lineNbr = line;
  }

  public Account.Id getAuthor() {
    return author;
  }

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

  public void setRealAuthor(Account.Id id) {
    // Use null for same real author, as before the column was added.
    realAuthor = Objects.equals(getAuthor(), id) ? null : id;
  }

  public Timestamp getWrittenOn() {
    return writtenOn;
  }

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

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

  public short getSide() {
    return side;
  }

  public void setSide(short s) {
    side = s;
  }

  public String getMessage() {
    return message;
  }

  public void setMessage(String s) {
    message = s;
  }

  public void setWrittenOn(Timestamp ts) {
    writtenOn = ts;
  }

  public String getParentUuid() {
    return parentUuid;
  }

  public void setParentUuid(String inReplyTo) {
    parentUuid = inReplyTo;
  }

  public void setRange(Range r) {
    if (r != null) {
      range =
          new CommentRange(
              r.startLine, r.startCharacter,
              r.endLine, r.endCharacter);
    } else {
      range = null;
    }
  }

  public void setRange(CommentRange r) {
    range = r;
  }

  public CommentRange getRange() {
    return range;
  }

  public void setRevId(RevId rev) {
    revId = rev;
  }

  public RevId getRevId() {
    return revId;
  }

  public void setTag(String tag) {
    this.tag = tag;
  }

  public String getTag() {
    return tag;
  }

  public void setUnresolved(Boolean unresolved) {
    this.unresolved = unresolved;
  }

  public Boolean getUnresolved() {
    return unresolved;
  }

  public Comment asComment(String serverId) {
    Comment c =
        new Comment(key.asCommentKey(), author, writtenOn, side, message, serverId, unresolved);
    c.setRevId(revId);
    c.setRange(range);
    c.lineNbr = lineNbr;
    c.parentUuid = parentUuid;
    c.tag = tag;
    c.setRealAuthor(getRealAuthor());
    return c;
  }

  @Override
  public boolean equals(Object o) {
    if (o instanceof PatchLineComment) {
      PatchLineComment c = (PatchLineComment) o;
      return Objects.equals(key, c.getKey())
          && Objects.equals(lineNbr, c.getLine())
          && Objects.equals(author, c.getAuthor())
          && Objects.equals(writtenOn, c.getWrittenOn())
          && Objects.equals(status, c.getStatus().getCode())
          && Objects.equals(side, c.getSide())
          && Objects.equals(message, c.getMessage())
          && Objects.equals(parentUuid, c.getParentUuid())
          && Objects.equals(range, c.getRange())
          && Objects.equals(revId, c.getRevId())
          && Objects.equals(tag, c.getTag())
          && Objects.equals(unresolved, c.getUnresolved());
    }
    return false;
  }

  @Override
  public int hashCode() {
    return key.hashCode();
  }

  @Override
  public String toString() {
    StringBuilder builder = new StringBuilder();
    builder.append("PatchLineComment{");
    builder.append("key=").append(key).append(',');
    builder.append("lineNbr=").append(lineNbr).append(',');
    builder.append("author=").append(author.get()).append(',');
    builder.append("realAuthor=").append(realAuthor != null ? realAuthor.get() : "").append(',');
    builder.append("writtenOn=").append(writtenOn.toString()).append(',');
    builder.append("status=").append(status).append(',');
    builder.append("side=").append(side).append(',');
    builder.append("message=").append(Objects.toString(message, "")).append(',');
    builder.append("parentUuid=").append(Objects.toString(parentUuid, "")).append(',');
    builder.append("range=").append(Objects.toString(range, "")).append(',');
    builder.append("revId=").append(revId != null ? revId.get() : "").append(',');
    builder.append("tag=").append(Objects.toString(tag, "")).append(',');
    builder.append("unresolved=").append(unresolved);
    builder.append('}');
    return builder.toString();
  }
}
