//  Copyright (C) 2020 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.server.patch.filediff;

import static com.google.gerrit.server.patch.DiffUtil.stringSize;

import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableList;
import com.google.gerrit.entities.Patch;
import com.google.gerrit.entities.Patch.ChangeType;
import com.google.gerrit.entities.Patch.PatchType;
import com.google.gerrit.proto.Protos;
import com.google.gerrit.server.cache.proto.Cache.FileDiffOutputProto;
import com.google.gerrit.server.cache.serialize.CacheSerializer;
import com.google.gerrit.server.cache.serialize.ObjectIdConverter;
import com.google.gerrit.server.patch.ComparisonType;
import com.google.protobuf.Descriptors.FieldDescriptor;
import java.io.Serializable;
import java.util.Optional;
import java.util.stream.Collectors;
import org.eclipse.jgit.lib.ObjectId;

/** File diff for a single file path. Produced as output of the {@link FileDiffCache}. */
@AutoValue
public abstract class FileDiffOutput implements Serializable {
  private static final long serialVersionUID = 1L;

  /** The 20 bytes SHA-1 object ID of the old git commit used in the diff. */
  public abstract ObjectId oldCommitId();

  /** The 20 bytes SHA-1 object ID of the new git commit used in the diff. */
  public abstract ObjectId newCommitId();

  /** Comparison type of old and new commits: against another patchset, parent or auto-merge. */
  public abstract ComparisonType comparisonType();

  /**
   * The file path at the old commit. Returns an empty Optional if {@link #changeType()} is equal to
   * {@link ChangeType#ADDED}.
   */
  public abstract Optional<String> oldPath();

  /**
   * The file path at the new commit. Returns an empty optional if {@link #changeType()} is equal to
   * {@link ChangeType#DELETED}.
   */
  public abstract Optional<String> newPath();

  /** The change type of the underlying file, e.g. added, deleted, renamed, etc... */
  public abstract Patch.ChangeType changeType();

  /** The patch type of the underlying file, e.g. unified, binary , etc... */
  public abstract Optional<Patch.PatchType> patchType();

  /**
   * A list of strings representation of the header lines of the {@link
   * org.eclipse.jgit.patch.FileHeader} that is produced as output of the diff.
   */
  public abstract ImmutableList<String> headerLines();

  /** The list of edits resulting from the diff hunks of the file. */
  public abstract ImmutableList<TaggedEdit> edits();

  /** The file size at the new commit. */
  public abstract long size();

  /** Difference in file size between the old and new commits. */
  public abstract long sizeDelta();

  /**
   * Returns {@code true} if the diff computation was not able to compute a diff, i.e. for diffs
   * taking a very long time to compute. We cache negative result in this case.
   */
  public abstract Optional<Boolean> negative();

  public abstract Builder toBuilder();

  /** A boolean indicating if all underlying edits of the file diff are due to rebase. */
  public boolean allEditsDueToRebase() {
    return !edits().isEmpty() && edits().stream().allMatch(TaggedEdit::dueToRebase);
  }

  /** Returns the number of inserted lines for the file diff. */
  public int insertions() {
    int ins = 0;
    for (TaggedEdit e : edits()) {
      if (!e.dueToRebase()) {
        ins += e.edit().endB() - e.edit().beginB();
      }
    }
    return ins;
  }

  /** Returns the number of deleted lines for the file diff. */
  public int deletions() {
    int del = 0;
    for (TaggedEdit e : edits()) {
      if (!e.dueToRebase()) {
        del += e.edit().endA() - e.edit().beginA();
      }
    }
    return del;
  }

  /** Returns an entity representing an unchanged file between two commits. */
  public static FileDiffOutput empty(String filePath, ObjectId oldCommitId, ObjectId newCommitId) {
    return builder()
        .oldCommitId(oldCommitId)
        .newCommitId(newCommitId)
        .comparisonType(ComparisonType.againstOtherPatchSet()) // not important
        .oldPath(Optional.empty())
        .newPath(Optional.of(filePath))
        .changeType(ChangeType.MODIFIED)
        .headerLines(ImmutableList.of())
        .edits(ImmutableList.of())
        .size(0)
        .sizeDelta(0)
        .build();
  }

  public static FileDiffOutput createNegative(
      String filePath, ObjectId oldCommitId, ObjectId newCommitId) {
    return empty(filePath, oldCommitId, newCommitId).toBuilder().build();
  }

  /** Returns true if this entity represents an unchanged file between two commits. */
  public boolean isEmpty() {
    return headerLines().isEmpty() && edits().isEmpty();
  }

  /**
   * Returns {@code true} if the diff computation was not able to compute a diff. We cache negative
   * result in this case.
   */
  public boolean isNegative() {
    return negative().isPresent() && negative().get();
  }

  public static Builder builder() {
    return new AutoValue_FileDiffOutput.Builder();
  }

  public int weight() {
    int result = 0;
    if (oldPath().isPresent()) {
      result += stringSize(oldPath().get());
    }
    if (newPath().isPresent()) {
      result += stringSize(newPath().get());
    }
    result += 20 + 20; // old and new commit IDs
    result += 4; // comparison type
    result += 4; // changeType
    if (patchType().isPresent()) {
      result += 4;
    }
    result += 4 + 4; // insertions and deletions
    result += 4 + 4; // size and size delta
    result += 20 * edits().size(); // each edit is 4 Integers + boolean = 4 * 4 + 4 = 20
    for (String s : headerLines()) {
      s += stringSize(s);
    }
    if (negative().isPresent()) {
      result += 1;
    }
    return result;
  }

  @AutoValue.Builder
  public abstract static class Builder {

    public abstract Builder oldCommitId(ObjectId value);

    public abstract Builder newCommitId(ObjectId value);

    public abstract Builder comparisonType(ComparisonType value);

    public abstract Builder oldPath(Optional<String> value);

    public abstract Builder newPath(Optional<String> value);

    public abstract Builder changeType(ChangeType value);

    public abstract Builder patchType(Optional<PatchType> value);

    public abstract Builder headerLines(ImmutableList<String> value);

    public abstract Builder edits(ImmutableList<TaggedEdit> value);

    public abstract Builder size(long value);

    public abstract Builder sizeDelta(long value);

    public abstract Builder negative(Optional<Boolean> value);

    public abstract FileDiffOutput build();
  }

  public enum Serializer implements CacheSerializer<FileDiffOutput> {
    INSTANCE;

    private static final FieldDescriptor OLD_PATH_DESCRIPTOR =
        FileDiffOutputProto.getDescriptor().findFieldByNumber(1);

    private static final FieldDescriptor NEW_PATH_DESCRIPTOR =
        FileDiffOutputProto.getDescriptor().findFieldByNumber(2);

    private static final FieldDescriptor PATCH_TYPE_DESCRIPTOR =
        FileDiffOutputProto.getDescriptor().findFieldByNumber(4);

    private static final FieldDescriptor NEGATIVE_DESCRIPTOR =
        FileDiffOutputProto.getDescriptor().findFieldByNumber(12);

    @Override
    public byte[] serialize(FileDiffOutput fileDiff) {
      ObjectIdConverter idConverter = ObjectIdConverter.create();
      FileDiffOutputProto.Builder builder =
          FileDiffOutputProto.newBuilder()
              .setOldCommit(idConverter.toByteString(fileDiff.oldCommitId().toObjectId()))
              .setNewCommit(idConverter.toByteString(fileDiff.newCommitId().toObjectId()))
              .setComparisonType(fileDiff.comparisonType().toProto())
              .setSize(fileDiff.size())
              .setSizeDelta(fileDiff.sizeDelta())
              .addAllHeaderLines(fileDiff.headerLines())
              .setChangeType(fileDiff.changeType().name())
              .addAllEdits(
                  fileDiff.edits().stream()
                      .map(
                          e ->
                              FileDiffOutputProto.TaggedEdit.newBuilder()
                                  .setEdit(
                                      FileDiffOutputProto.Edit.newBuilder()
                                          .setBeginA(e.edit().beginA())
                                          .setEndA(e.edit().endA())
                                          .setBeginB(e.edit().beginB())
                                          .setEndB(e.edit().endB())
                                          .build())
                                  .setDueToRebase(e.dueToRebase())
                                  .build())
                      .collect(Collectors.toList()));

      if (fileDiff.oldPath().isPresent()) {
        builder.setOldPath(fileDiff.oldPath().get());
      }

      if (fileDiff.newPath().isPresent()) {
        builder.setNewPath(fileDiff.newPath().get());
      }

      if (fileDiff.patchType().isPresent()) {
        builder.setPatchType(fileDiff.patchType().get().name());
      }

      if (fileDiff.negative().isPresent()) {
        builder.setNegative(fileDiff.negative().get());
      }

      return Protos.toByteArray(builder.build());
    }

    @Override
    public FileDiffOutput deserialize(byte[] in) {
      ObjectIdConverter idConverter = ObjectIdConverter.create();
      FileDiffOutputProto proto = Protos.parseUnchecked(FileDiffOutputProto.parser(), in);
      FileDiffOutput.Builder builder = FileDiffOutput.builder();
      builder
          .oldCommitId(idConverter.fromByteString(proto.getOldCommit()))
          .newCommitId(idConverter.fromByteString(proto.getNewCommit()))
          .comparisonType(ComparisonType.fromProto(proto.getComparisonType()))
          .size(proto.getSize())
          .sizeDelta(proto.getSizeDelta())
          .headerLines(proto.getHeaderLinesList().stream().collect(ImmutableList.toImmutableList()))
          .changeType(ChangeType.valueOf(proto.getChangeType()))
          .edits(
              proto.getEditsList().stream()
                  .map(
                      e ->
                          TaggedEdit.create(
                              Edit.create(
                                  e.getEdit().getBeginA(),
                                  e.getEdit().getEndA(),
                                  e.getEdit().getBeginB(),
                                  e.getEdit().getEndB()),
                              e.getDueToRebase()))
                  .collect(ImmutableList.toImmutableList()));

      if (proto.hasField(OLD_PATH_DESCRIPTOR)) {
        builder.oldPath(Optional.of(proto.getOldPath()));
      }
      if (proto.hasField(NEW_PATH_DESCRIPTOR)) {
        builder.newPath(Optional.of(proto.getNewPath()));
      }
      if (proto.hasField(PATCH_TYPE_DESCRIPTOR)) {
        builder.patchType(Optional.of(Patch.PatchType.valueOf(proto.getPatchType())));
      }
      if (proto.hasField(NEGATIVE_DESCRIPTOR)) {
        builder.negative(Optional.of(proto.getNegative()));
      }
      return builder.build();
    }
  }
}
