// 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.common.collect.ImmutableList.toImmutableList;
import static com.google.common.collect.ImmutableSet.toImmutableSet;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.gerrit.common.data.PatchScript;
import com.google.gerrit.common.data.PatchScript.DisplayMethod;
import com.google.gerrit.entities.FixReplacement;
import com.google.gerrit.entities.Patch;
import com.google.gerrit.entities.Patch.ChangeType;
import com.google.gerrit.entities.Patch.PatchType;
import com.google.gerrit.extensions.client.DiffPreferencesInfo;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.server.fixes.FixCalculator;
import com.google.gerrit.server.mime.FileTypeRegistry;
import com.google.gerrit.server.patch.DiffContentCalculator.DiffCalculatorResult;
import com.google.gerrit.server.patch.DiffContentCalculator.TextSource;
import com.google.gerrit.server.patch.filediff.FileDiffOutput;
import com.google.gerrit.server.patch.filediff.TaggedEdit;
import com.google.inject.Inject;
import eu.medsea.mimeutil.MimeType;
import eu.medsea.mimeutil.MimeUtil2;
import java.io.IOException;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import org.eclipse.jgit.diff.Edit;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.treewalk.TreeWalk;

class PatchScriptBuilder {

  private DiffPreferencesInfo diffPrefs;
  private final FileTypeRegistry registry;
  private IntraLineDiffCalculator intralineDiffCalculator;

  @Inject
  PatchScriptBuilder(FileTypeRegistry ftr) {
    registry = ftr;
  }

  void setDiffPrefs(DiffPreferencesInfo dp) {
    diffPrefs = dp;
  }

  void setIntraLineDiffCalculator(IntraLineDiffCalculator calculator) {
    intralineDiffCalculator = calculator;
  }

  /** Convert into {@link PatchScript} using the old diff cache output. */
  PatchScript toPatchScriptOld(Repository git, PatchList list, PatchListEntry content)
      throws IOException {

    PatchFileChange change =
        new PatchFileChange(
            content.getEdits(),
            content.getEditsDueToRebase(),
            content.getHeaderLines(),
            content.getOldName(),
            content.getNewName(),
            content.getChangeType(),
            content.getPatchType());
    SidesResolver sidesResolver = new SidesResolver(git, list.getComparisonType());
    ResolvedSides sides =
        resolveSides(
            git, sidesResolver, oldName(change), newName(change), list.getOldId(), list.getNewId());
    return build(sides.a, sides.b, change);
  }

  /** Convert into {@link PatchScript} using the new diff cache output. */
  PatchScript toPatchScriptNew(Repository git, FileDiffOutput content) throws IOException {
    PatchFileChange change =
        new PatchFileChange(
            content.edits().stream().map(TaggedEdit::jgitEdit).collect(toImmutableList()),
            content.edits().stream()
                .filter(TaggedEdit::dueToRebase)
                .map(TaggedEdit::jgitEdit)
                .collect(toImmutableSet()),
            content.headerLines(),
            FilePathAdapter.getOldPath(content.oldPath(), content.changeType()),
            FilePathAdapter.getNewPath(content.oldPath(), content.newPath(), content.changeType()),
            content.changeType(),
            content.patchType().orElse(null));
    SidesResolver sidesResolver = new SidesResolver(git, content.comparisonType());
    ResolvedSides sides =
        resolveSides(
            git,
            sidesResolver,
            oldName(change),
            newName(change),
            content.oldCommitId(),
            content.newCommitId());
    return build(sides.a, sides.b, change);
  }

  private ResolvedSides resolveSides(
      Repository git,
      SidesResolver sidesResolver,
      String oldName,
      String newName,
      ObjectId aId,
      ObjectId bId)
      throws IOException {
    try (ObjectReader reader = git.newObjectReader()) {
      PatchSide a = sidesResolver.resolve(registry, reader, oldName, null, aId, true);
      PatchSide b =
          sidesResolver.resolve(registry, reader, newName, a, bId, Objects.equals(aId, bId));
      return new ResolvedSides(a, b);
    }
  }

  PatchScript toPatchScript(
      Repository git, ObjectId baseId, String fileName, List<FixReplacement> fixReplacements)
      throws IOException, ResourceConflictException, ResourceNotFoundException {
    SidesResolver sidesResolver = new SidesResolver(git, ComparisonType.againstOtherPatchSet());
    PatchSide a = resolveSideA(git, sidesResolver, fileName, baseId);
    if (a.mode == FileMode.MISSING) {
      throw new ResourceNotFoundException(String.format("File %s not found", fileName));
    }
    FixCalculator.FixResult fixResult = FixCalculator.calculateFix(a.src, fixReplacements);
    PatchSide b =
        new PatchSide(
            null,
            fileName,
            ObjectId.zeroId(),
            a.mode,
            fixResult.text.getContent(),
            fixResult.text,
            a.mimeType,
            a.displayMethod,
            a.fileMode);

    PatchFileChange change =
        new PatchFileChange(
            fixResult.edits,
            ImmutableSet.of(),
            ImmutableList.of(),
            fileName,
            fileName,
            ChangeType.MODIFIED,
            PatchType.UNIFIED);

    return build(a, b, change);
  }

  private PatchSide resolveSideA(
      Repository git, SidesResolver sidesResolver, String path, ObjectId baseId)
      throws IOException {
    try (ObjectReader reader = git.newObjectReader()) {
      return sidesResolver.resolve(registry, reader, path, null, baseId, true);
    }
  }

  private PatchScript build(PatchSide a, PatchSide b, PatchFileChange content) {
    ImmutableList<Edit> contentEdits = content.getEdits();
    ImmutableSet<Edit> editsDueToRebase = content.getEditsDueToRebase();

    IntraLineDiffCalculatorResult intralineResult = IntraLineDiffCalculatorResult.NO_RESULT;

    if (isModify(content) && intralineDiffCalculator != null && isIntralineModeAllowed(b)) {
      intralineResult =
          intralineDiffCalculator.calculateIntraLineDiff(
              contentEdits, editsDueToRebase, a.id, b.id, a.src, b.src, b.treeId, b.path);
    }
    ImmutableList<Edit> finalEdits = intralineResult.edits.orElse(contentEdits);
    DiffContentCalculator calculator = new DiffContentCalculator(diffPrefs);
    DiffCalculatorResult diffCalculatorResult =
        calculator.calculateDiffContent(new TextSource(a.src), new TextSource(b.src), finalEdits);

    return new PatchScript(
        content.getChangeType(),
        content.getOldName(),
        content.getNewName(),
        a.fileMode,
        b.fileMode,
        content.getHeaderLines(),
        diffPrefs,
        diffCalculatorResult.diffContent.a,
        diffCalculatorResult.diffContent.b,
        diffCalculatorResult.edits,
        editsDueToRebase,
        a.displayMethod,
        b.displayMethod,
        a.mimeType,
        b.mimeType,
        intralineResult.failure,
        intralineResult.timeout,
        content.getPatchType() == Patch.PatchType.BINARY,
        a.treeId == null ? null : a.treeId.getName(),
        b.treeId == null ? null : b.treeId.getName());
  }

  private static boolean isModify(PatchFileChange content) {
    switch (content.getChangeType()) {
      case MODIFIED:
      case COPIED:
      case RENAMED:
      case REWRITE:
        return true;

      case ADDED:
      case DELETED:
      default:
        return false;
    }
  }

  private static String oldName(PatchFileChange entry) {
    switch (entry.getChangeType()) {
      case ADDED:
        return null;
      case DELETED:
      case MODIFIED:
      case REWRITE:
        return entry.getNewName();
      case COPIED:
      case RENAMED:
      default:
        return entry.getOldName();
    }
  }

  private static String newName(PatchFileChange entry) {
    switch (entry.getChangeType()) {
      case DELETED:
        return null;
      case ADDED:
      case MODIFIED:
      case COPIED:
      case RENAMED:
      case REWRITE:
      default:
        return entry.getNewName();
    }
  }

  private static boolean isIntralineModeAllowed(PatchSide side) {
    // The intraline diff cache keys are the same for these cases. It's better to not show
    // intraline results than showing completely wrong diffs or to run into a server error.
    return !Patch.isMagic(side.path) && !isSubmoduleCommit(side.mode);
  }

  private static boolean isSubmoduleCommit(FileMode mode) {
    return mode.getObjectType() == Constants.OBJ_COMMIT;
  }

  private static class PatchSide {
    final ObjectId treeId;
    final String path;
    final ObjectId id;
    final FileMode mode;
    final byte[] srcContent;
    final Text src;
    final String mimeType;
    final DisplayMethod displayMethod;
    final PatchScript.FileMode fileMode;

    private PatchSide(
        ObjectId treeId,
        String path,
        ObjectId id,
        FileMode mode,
        byte[] srcContent,
        Text src,
        String mimeType,
        DisplayMethod displayMethod,
        PatchScript.FileMode fileMode) {
      this.treeId = treeId;
      this.path = path;
      this.id = id;
      this.mode = mode;
      this.srcContent = srcContent;
      this.src = src;
      this.mimeType = mimeType;
      this.displayMethod = displayMethod;
      this.fileMode = fileMode;
    }
  }

  private static class ResolvedSides {
    // Not an @AutoValue because PatchSide can't be AutoValue
    public final PatchSide a;
    public final PatchSide b;

    ResolvedSides(PatchSide a, PatchSide b) {
      this.a = a;
      this.b = b;
    }
  }

  static class SidesResolver {

    private final Repository db;
    private final ComparisonType comparisonType;

    SidesResolver(Repository db, ComparisonType comparisonType) {
      this.db = db;
      this.comparisonType = comparisonType;
    }

    PatchSide resolve(
        final FileTypeRegistry registry,
        final ObjectReader reader,
        final String path,
        final PatchSide other,
        final ObjectId within,
        final boolean isWithinEqualsA)
        throws IOException {
      try {
        boolean isCommitMsg = Patch.COMMIT_MSG.equals(path);
        boolean isMergeList = Patch.MERGE_LIST.equals(path);
        if (isCommitMsg || isMergeList) {
          if (comparisonType.isAgainstParentOrAutoMerge() && isWithinEqualsA) {
            return createSide(
                within,
                path,
                ObjectId.zeroId(),
                FileMode.MISSING,
                Text.NO_BYTES,
                Text.EMPTY,
                MimeUtil2.UNKNOWN_MIME_TYPE.toString(),
                DisplayMethod.NONE,
                false);
          }
          Text src =
              isCommitMsg
                  ? Text.forCommit(reader, within)
                  : Text.forMergeList(comparisonType, reader, within);
          byte[] srcContent = src.getContent();
          DisplayMethod displayMethod;
          FileMode mode;
          if (src == Text.EMPTY) {
            mode = FileMode.MISSING;
            displayMethod = DisplayMethod.NONE;
          } else {
            mode = FileMode.REGULAR_FILE;
            displayMethod = DisplayMethod.DIFF;
          }
          return createSide(
              within,
              path,
              within,
              mode,
              srcContent,
              src,
              MimeUtil2.UNKNOWN_MIME_TYPE.toString(),
              displayMethod,
              false);
        }
        final TreeWalk tw = find(reader, path, within);
        ObjectId id = tw != null ? tw.getObjectId(0) : ObjectId.zeroId();
        FileMode mode = tw != null ? tw.getFileMode(0) : FileMode.MISSING;
        boolean reuse =
            other != null
                && other.id.equals(id)
                && (other.mode == mode || isBothFile(other.mode, mode));
        Text src = null;
        byte[] srcContent;
        if (reuse) {
          srcContent = other.srcContent;
        } else {
          srcContent = SrcContentResolver.getSourceContent(db, id, mode);
        }
        String mimeType = MimeUtil2.UNKNOWN_MIME_TYPE.toString();
        DisplayMethod displayMethod = DisplayMethod.DIFF;
        if (reuse) {
          mimeType = other.mimeType;
          displayMethod = other.displayMethod;
          src = other.src;

        } else if (srcContent.length > 0 && FileMode.SYMLINK != mode) {
          MimeType registryMimeType = registry.getMimeType(path, srcContent);
          if ("image".equals(registryMimeType.getMediaType())
              && registry.isSafeInline(registryMimeType)) {
            displayMethod = DisplayMethod.IMG;
          }
          mimeType = registryMimeType.toString();
        }
        return createSide(within, path, id, mode, srcContent, src, mimeType, displayMethod, reuse);

      } catch (IOException err) {
        throw new IOException("Cannot read " + within.name() + ":" + path, err);
      }
    }

    private PatchSide createSide(
        ObjectId treeId,
        String path,
        ObjectId id,
        FileMode mode,
        byte[] srcContent,
        Text src,
        String mimeType,
        DisplayMethod displayMethod,
        boolean reuse) {
      if (!reuse) {
        if (srcContent == Text.NO_BYTES) {
          src = Text.EMPTY;
        } else {
          src = new Text(srcContent);
        }
      }
      if (mode == FileMode.MISSING) {
        displayMethod = DisplayMethod.NONE;
      }
      PatchScript.FileMode fileMode = PatchScript.FileMode.fromJgitFileMode(mode);
      return new PatchSide(
          treeId, path, id, mode, srcContent, src, mimeType, displayMethod, fileMode);
    }

    private TreeWalk find(ObjectReader reader, String path, ObjectId within) throws IOException {
      if (path == null || within == null) {
        return null;
      }
      try (RevWalk rw = new RevWalk(reader)) {
        final RevTree tree = rw.parseTree(within);
        return TreeWalk.forPath(reader, path, tree);
      }
    }
  }

  private static boolean isBothFile(FileMode a, FileMode b) {
    return (a.getBits() & FileMode.TYPE_FILE) == FileMode.TYPE_FILE
        && (b.getBits() & FileMode.TYPE_FILE) == FileMode.TYPE_FILE;
  }

  static class IntraLineDiffCalculatorResult {
    // Not an @AutoValue because Edit is mutable
    final boolean failure;
    final boolean timeout;
    private final Optional<ImmutableList<Edit>> edits;

    private IntraLineDiffCalculatorResult(
        Optional<ImmutableList<Edit>> edits, boolean failure, boolean timeout) {
      this.failure = failure;
      this.timeout = timeout;
      this.edits = edits;
    }

    static final IntraLineDiffCalculatorResult NO_RESULT =
        new IntraLineDiffCalculatorResult(Optional.empty(), false, false);
    static final IntraLineDiffCalculatorResult FAILURE =
        new IntraLineDiffCalculatorResult(Optional.empty(), true, false);
    static final IntraLineDiffCalculatorResult TIMEOUT =
        new IntraLineDiffCalculatorResult(Optional.empty(), false, true);

    static IntraLineDiffCalculatorResult success(ImmutableList<Edit> edits) {
      return new IntraLineDiffCalculatorResult(Optional.of(edits), false, false);
    }
  }

  interface IntraLineDiffCalculator {

    IntraLineDiffCalculatorResult calculateIntraLineDiff(
        ImmutableList<Edit> edits,
        Set<Edit> editsDueToRebase,
        ObjectId aId,
        ObjectId bId,
        Text aSrc,
        Text bSrc,
        ObjectId bTreeId,
        String bPath);
  }

  static class PatchFileChange {
    private final ImmutableList<Edit> edits;
    private final ImmutableSet<Edit> editsDueToRebase;
    private final ImmutableList<String> headerLines;
    private final String oldName;
    private final String newName;
    private final ChangeType changeType;
    private final Patch.PatchType patchType;

    public PatchFileChange(
        ImmutableList<Edit> edits,
        ImmutableSet<Edit> editsDueToRebase,
        ImmutableList<String> headerLines,
        String oldName,
        String newName,
        ChangeType changeType,
        Patch.PatchType patchType) {
      this.edits = edits;
      this.editsDueToRebase = editsDueToRebase;
      this.headerLines = headerLines;
      this.oldName = oldName;
      this.newName = newName;
      this.changeType = changeType;
      this.patchType = patchType;
    }

    ImmutableList<Edit> getEdits() {
      return edits;
    }

    ImmutableSet<Edit> getEditsDueToRebase() {
      return editsDueToRebase;
    }

    ImmutableList<String> getHeaderLines() {
      return headerLines;
    }

    String getNewName() {
      return newName;
    }

    String getOldName() {
      return oldName;
    }

    ChangeType getChangeType() {
      return changeType;
    }

    Patch.PatchType getPatchType() {
      return patchType;
    }
  }
}
