// Copyright (C) 2017 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.edit.tree;

import static com.google.gerrit.entities.Patch.FileMode.EXECUTABLE_FILE;
import static com.google.gerrit.entities.Patch.FileMode.REGULAR_FILE;
import static java.util.Objects.requireNonNull;
import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.io.ByteStreams;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.extensions.restapi.RawInput;
import java.io.IOException;
import java.io.InputStream;
import java.time.Instant;
import java.util.Collections;
import java.util.List;
import org.eclipse.jgit.dircache.DirCacheEditor;
import org.eclipse.jgit.dircache.DirCacheEntry;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.Repository;

/** A {@code TreeModification} which changes the content of a file. */
public class ChangeFileContentModification implements TreeModification {
  private final String filePath;
  private final RawInput newContent;
  private final Integer newGitFileMode;

  public ChangeFileContentModification(String filePath, RawInput newContent) {
    this.filePath = filePath;
    this.newContent = requireNonNull(newContent, "new content required");
    this.newGitFileMode = null;
  }

  public ChangeFileContentModification(
      String filePath, RawInput newContent, @Nullable Integer newGitFileMode) {
    this.filePath = filePath;
    this.newContent = requireNonNull(newContent, "new content required");
    this.newGitFileMode = newGitFileMode;
  }

  @Override
  public List<DirCacheEditor.PathEdit> getPathEdits(
      Repository repository, ObjectId treeId, ImmutableList<? extends ObjectId> parents) {
    DirCacheEditor.PathEdit changeContentEdit =
        new ChangeContent(filePath, newContent, repository, newGitFileMode);
    return Collections.singletonList(changeContentEdit);
  }

  @Override
  public ImmutableSet<String> getFilePaths() {
    return ImmutableSet.of(filePath);
  }

  public RawInput getNewContent() {
    return newContent;
  }

  /** A {@code PathEdit} which changes the contents of a file. */
  private static class ChangeContent extends DirCacheEditor.PathEdit {

    private final RawInput newContent;
    private final Repository repository;
    private final Integer newGitFileMode;

    ChangeContent(
        String filePath,
        RawInput newContent,
        Repository repository,
        @Nullable Integer newGitFileMode) {
      super(filePath);
      this.newContent = newContent;
      this.repository = repository;
      this.newGitFileMode = newGitFileMode;
    }

    private boolean isValidGitFileMode(int gitFileMode) {
      return (gitFileMode == EXECUTABLE_FILE.getMode()) || (gitFileMode == REGULAR_FILE.getMode());
    }

    @Override
    public void apply(DirCacheEntry dirCacheEntry) {
      try {
        if (newGitFileMode != null && newGitFileMode != 0) {
          if (!isValidGitFileMode(newGitFileMode)) {
            throw new IllegalStateException("GitFileMode " + newGitFileMode + " is invalid");
          }
          dirCacheEntry.setFileMode(FileMode.fromBits(newGitFileMode));
        }
        if (dirCacheEntry.getFileMode() == FileMode.GITLINK) {
          dirCacheEntry.setLength(0);
          dirCacheEntry.setLastModified(Instant.EPOCH);
          ObjectId newObjectId = ObjectId.fromString(getNewContentBytes(), 0);
          dirCacheEntry.setObjectId(newObjectId);
        } else {
          if (dirCacheEntry.getRawMode() == 0) {
            dirCacheEntry.setFileMode(FileMode.REGULAR_FILE);
          }
          ObjectId newBlobObjectId = createNewBlobAndGetItsId();
          dirCacheEntry.setObjectId(newBlobObjectId);
        }
      } catch (IOException e) {
        String message =
            String.format("Could not change the content of %s", dirCacheEntry.getPathString());
        throw new IllegalStateException(message, e);
      }
    }

    private ObjectId createNewBlobAndGetItsId() throws IOException {
      try (ObjectInserter objectInserter = repository.newObjectInserter()) {
        ObjectId blobObjectId = createNewBlobAndGetItsId(objectInserter);
        objectInserter.flush();
        return blobObjectId;
      }
    }

    private ObjectId createNewBlobAndGetItsId(ObjectInserter objectInserter) throws IOException {
      long contentLength = newContent.getContentLength();
      if (contentLength < 0) {
        return objectInserter.insert(OBJ_BLOB, getNewContentBytes());
      }
      InputStream contentInputStream = newContent.getInputStream();
      return objectInserter.insert(OBJ_BLOB, contentLength, contentInputStream);
    }

    private byte[] getNewContentBytes() throws IOException {
      return ByteStreams.toByteArray(newContent.getInputStream());
    }
  }
}
