// 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.readEnum;
import static com.google.gerrit.server.ioutil.BasicSerialization.readString;
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.writeEnum;
import static com.google.gerrit.server.ioutil.BasicSerialization.writeString;
import static com.google.gerrit.server.ioutil.BasicSerialization.writeVarInt32;

import com.google.gerrit.reviewdb.client.Patch;
import com.google.gerrit.reviewdb.client.Patch.ChangeType;
import com.google.gerrit.reviewdb.client.Patch.PatchType;
import com.google.gerrit.reviewdb.client.PatchSet;

import org.eclipse.jgit.diff.Edit;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.patch.CombinedFileHeader;
import org.eclipse.jgit.patch.FileHeader;
import org.eclipse.jgit.util.IntList;
import org.eclipse.jgit.util.RawParseUtils;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class PatchListEntry {
  private static final byte[] EMPTY_HEADER = {};

  static PatchListEntry empty(final String fileName) {
    return new PatchListEntry(ChangeType.MODIFIED, PatchType.UNIFIED, null,
        fileName, EMPTY_HEADER, Collections.<Edit> emptyList(), 0, 0);
  }

  private final ChangeType changeType;
  private final PatchType patchType;
  private final String oldName;
  private final String newName;
  private final byte[] header;
  private final List<Edit> edits;
  private final int insertions;
  private final int deletions;

  PatchListEntry(final FileHeader hdr, List<Edit> editList) {
    changeType = toChangeType(hdr);
    patchType = toPatchType(hdr);

    switch (changeType) {
      case DELETED:
        oldName = null;
        newName = hdr.getOldPath();
        break;

      case ADDED:
      case MODIFIED:
        oldName = null;
        newName = hdr.getNewPath();
        break;

      case COPIED:
      case RENAMED:
        oldName = hdr.getOldPath();
        newName = hdr.getNewPath();
        break;

      default:
        throw new IllegalArgumentException("Unsupported type " + changeType);
    }

    header = compact(hdr);

    if (hdr instanceof CombinedFileHeader
        || hdr.getHunks().isEmpty() //
        || hdr.getOldMode() == FileMode.GITLINK
        || hdr.getNewMode() == FileMode.GITLINK) {
      edits = Collections.emptyList();
    } else {
      edits = Collections.unmodifiableList(editList);
    }

    int ins = 0;
    int del = 0;
    for (Edit e : editList) {
      del += e.getEndA() - e.getBeginA();
      ins += e.getEndB() - e.getBeginB();
    }
    insertions = ins;
    deletions = del;
  }

  private PatchListEntry(final ChangeType changeType,
      final PatchType patchType, final String oldName, final String newName,
      final byte[] header, final List<Edit> edits, final int insertions,
      final int deletions) {
    this.changeType = changeType;
    this.patchType = patchType;
    this.oldName = oldName;
    this.newName = newName;
    this.header = header;
    this.edits = edits;
    this.insertions = insertions;
    this.deletions = deletions;
  }

  int weigh() {
    int size = 16 + 6*8 + 2*4 + 20 + 16+8+4+20;
    size += stringSize(oldName);
    size += stringSize(newName);
    size += header.length;
    size += (8 + 16 + 4*4) * edits.size();
    return size;
  }

  private static int stringSize(String str) {
    if (str != null) {
      return 16 + 3*4 + 16 + str.length() * 2;
    }
    return 0;
  }

  public ChangeType getChangeType() {
    return changeType;
  }

  public PatchType getPatchType() {
    return patchType;
  }

  public String getOldName() {
    return oldName;
  }

  public String getNewName() {
    return newName;
  }

  public List<Edit> getEdits() {
    return edits;
  }

  public int getInsertions() {
    return insertions;
  }

  public int getDeletions() {
    return deletions;
  }

  public List<String> getHeaderLines() {
    final IntList m = RawParseUtils.lineMap(header, 0, header.length);
    final List<String> headerLines = new ArrayList<>(m.size() - 1);
    for (int i = 1; i < m.size() - 1; i++) {
      final int b = m.get(i);
      int e = m.get(i + 1);
      if (header[e - 1] == '\n') {
        e--;
      }
      headerLines.add(RawParseUtils.decode(Constants.CHARSET, header, b, e));
    }
    return headerLines;
  }

  Patch toPatch(final PatchSet.Id setId) {
    final Patch p = new Patch(new Patch.Key(setId, getNewName()));
    p.setChangeType(getChangeType());
    p.setPatchType(getPatchType());
    p.setSourceFileName(getOldName());
    p.setInsertions(insertions);
    p.setDeletions(deletions);
    return p;
  }

  void writeTo(final OutputStream out) throws IOException {
    writeEnum(out, changeType);
    writeEnum(out, patchType);
    writeString(out, oldName);
    writeString(out, newName);
    writeBytes(out, header);
    writeVarInt32(out, insertions);
    writeVarInt32(out, deletions);

    writeVarInt32(out, edits.size());
    for (final Edit e : edits) {
      writeVarInt32(out, e.getBeginA());
      writeVarInt32(out, e.getEndA());
      writeVarInt32(out, e.getBeginB());
      writeVarInt32(out, e.getEndB());
    }
  }

  static PatchListEntry readFrom(final InputStream in) throws IOException {
    final ChangeType changeType = readEnum(in, ChangeType.values());
    final PatchType patchType = readEnum(in, PatchType.values());
    final String oldName = readString(in);
    final String newName = readString(in);
    final byte[] hdr = readBytes(in);
    final int ins = readVarInt32(in);
    final int del = readVarInt32(in);

    final int editCount = readVarInt32(in);
    final Edit[] editArray = new Edit[editCount];
    for (int i = 0; i < editCount; i++) {
      int beginA = readVarInt32(in);
      int endA = readVarInt32(in);
      int beginB = readVarInt32(in);
      int endB = readVarInt32(in);
      editArray[i] = new Edit(beginA, endA, beginB, endB);
    }

    return new PatchListEntry(changeType, patchType, oldName, newName, hdr,
        toList(editArray), ins, del);
  }

  private static List<Edit> toList(Edit[] l) {
    return Collections.unmodifiableList(Arrays.asList(l));
  }

  private static byte[] compact(final FileHeader h) {
    final int end = end(h);
    if (h.getStartOffset() == 0 && end == h.getBuffer().length) {
      return h.getBuffer();
    }

    final byte[] buf = new byte[end - h.getStartOffset()];
    System.arraycopy(h.getBuffer(), h.getStartOffset(), buf, 0, buf.length);
    return buf;
  }

  private static int end(final FileHeader h) {
    if (h instanceof CombinedFileHeader) {
      return h.getEndOffset();
    }
    if (!h.getHunks().isEmpty()) {
      return h.getHunks().get(0).getStartOffset();
    }
    return h.getEndOffset();
  }

  private static ChangeType toChangeType(final FileHeader hdr) {
    switch (hdr.getChangeType()) {
      case ADD:
        return Patch.ChangeType.ADDED;
      case MODIFY:
        return Patch.ChangeType.MODIFIED;
      case DELETE:
        return Patch.ChangeType.DELETED;
      case RENAME:
        return Patch.ChangeType.RENAMED;
      case COPY:
        return Patch.ChangeType.COPIED;
      default:
        throw new IllegalArgumentException("Unsupported type "
            + hdr.getChangeType());
    }
  }

  private static PatchType toPatchType(final FileHeader hdr) {
    PatchType pt;

    switch (hdr.getPatchType()) {
      case UNIFIED:
        pt = Patch.PatchType.UNIFIED;
        break;
      case GIT_BINARY:
      case BINARY:
        pt = Patch.PatchType.BINARY;
        break;
      default:
        throw new IllegalArgumentException("Unsupported type "
            + hdr.getPatchType());
    }

    if (pt != PatchType.BINARY) {
      final byte[] buf = hdr.getBuffer();
      for (int ptr = hdr.getStartOffset(); ptr < hdr.getEndOffset(); ptr++) {
        if (buf[ptr] == '\0') {
          // Its really binary, but Git couldn't see the nul early enough
          // to realize its binary, and instead produced the diff.
          //
          // Force it to be a binary; it really should have been that.
          //
          pt = PatchType.BINARY;
          break;
        }
      }
    }

    return pt;
  }
}
