// Copyright (C) 2009 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;

import static com.google.gerrit.server.ioutil.BasicSerialization.readBytes;
import static com.google.gerrit.server.ioutil.BasicSerialization.readVarInt32;
import static com.google.gerrit.server.ioutil.BasicSerialization.writeBytes;
import static com.google.gerrit.server.ioutil.BasicSerialization.writeVarInt32;
import static org.eclipse.jgit.lib.ObjectIdSerializer.read;
import static org.eclipse.jgit.lib.ObjectIdSerializer.readWithoutMarker;
import static org.eclipse.jgit.lib.ObjectIdSerializer.write;
import static org.eclipse.jgit.lib.ObjectIdSerializer.writeWithoutMarker;

import com.google.common.annotations.VisibleForTesting;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.entities.Patch;
import com.google.gerrit.git.ObjectIds;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.InflaterInputStream;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.ObjectId;

public class PatchList implements Serializable {
  private static final long serialVersionUID = PatchListKey.serialVersionUID;

  @VisibleForTesting
  static final Comparator<String> FILE_PATH_CMP =
      Comparator.comparing(Patch::isMagic).reversed().thenComparing(Comparator.naturalOrder());

  private static final Comparator<PatchListEntry> PATCH_CMP =
      Comparator.comparing(PatchListEntry::getNewName, FILE_PATH_CMP);

  @Nullable private transient ObjectId oldId;
  private transient ObjectId newId;
  private transient boolean isMerge;
  private transient ComparisonType comparisonType;
  private transient int insertions;
  private transient int deletions;
  private transient PatchListEntry[] patches;

  public PatchList(
      @Nullable AnyObjectId oldId,
      AnyObjectId newId,
      boolean isMerge,
      ComparisonType comparisonType,
      PatchListEntry[] patches) {
    this.oldId = ObjectIds.copyOrNull(oldId);
    this.newId = newId.copy();
    this.isMerge = isMerge;
    this.comparisonType = comparisonType;

    Arrays.sort(patches, 0, patches.length, PATCH_CMP);

    // Skip magic files
    int i = 0;
    for (; i < patches.length; i++) {
      if (!Patch.isMagic(patches[i].getNewName())) {
        break;
      }
    }
    for (; i < patches.length; i++) {
      insertions += patches[i].getInsertions();
      deletions += patches[i].getDeletions();
    }

    this.patches = patches;
  }

  /** Old side tree or commit; null only if this is a combined diff. */
  @Nullable
  public ObjectId getOldId() {
    return oldId;
  }

  /** New side commit. */
  public ObjectId getNewId() {
    return newId;
  }

  /** Get a sorted, unmodifiable list of all files in this list. */
  public List<PatchListEntry> getPatches() {
    return Collections.unmodifiableList(Arrays.asList(patches));
  }

  /** @return the comparison type */
  public ComparisonType getComparisonType() {
    return comparisonType;
  }

  /** @return total number of new lines added. */
  public int getInsertions() {
    return insertions;
  }

  /** @return total number of lines removed. */
  public int getDeletions() {
    return deletions;
  }

  /** Find an entry by name, returning an empty entry if not present. */
  public PatchListEntry get(String fileName) {
    final int index = search(fileName);
    return 0 <= index ? patches[index] : PatchListEntry.empty(fileName);
  }

  private int search(String fileName) {
    PatchListEntry want = PatchListEntry.empty(fileName);
    return Arrays.binarySearch(patches, 0, patches.length, want, PATCH_CMP);
  }

  private void writeObject(ObjectOutputStream output) throws IOException {
    final ByteArrayOutputStream buf = new ByteArrayOutputStream();
    try (DeflaterOutputStream out = new DeflaterOutputStream(buf)) {
      write(out, oldId);
      writeWithoutMarker(out, newId);
      writeVarInt32(out, isMerge ? 1 : 0);
      comparisonType.writeTo(out);
      writeVarInt32(out, insertions);
      writeVarInt32(out, deletions);
      writeVarInt32(out, patches.length);
      for (PatchListEntry p : patches) {
        p.writeTo(out);
      }
    }
    writeBytes(output, buf.toByteArray());
  }

  private void readObject(ObjectInputStream input) throws IOException {
    final ByteArrayInputStream buf = new ByteArrayInputStream(readBytes(input));
    try (InflaterInputStream in = new InflaterInputStream(buf)) {
      oldId = read(in);
      newId = readWithoutMarker(in);
      isMerge = readVarInt32(in) != 0;
      comparisonType = ComparisonType.readFrom(in);
      insertions = readVarInt32(in);
      deletions = readVarInt32(in);
      final int cnt = readVarInt32(in);
      final PatchListEntry[] all = new PatchListEntry[cnt];
      for (int i = 0; i < all.length; i++) {
        all[i] = PatchListEntry.readFrom(in);
      }
      patches = all;
    }
  }
}
