// 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.gerritforge.gerrit.globalrefdb.validation;

import com.gerritforge.gerrit.globalrefdb.validation.RefUpdateValidator.NoParameterFunction;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import java.io.IOException;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefDatabase;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.transport.PushCertificate;

/**
 * Creates, updates or deletes any reference after having checked the validity of this operation
 * against the global refdb.
 */
public class SharedRefDbRefUpdate extends RefUpdate {

  protected final RefUpdate refUpdateBase;
  private final String projectName;
  private final RefUpdateValidator.Factory refValidatorFactory;
  private final RefUpdateValidator refUpdateValidator;

  /** {@code SharedRefDbRefUpdate} Factory for Guice assisted injection. */
  public interface Factory {
    SharedRefDbRefUpdate create(
        String projectName,
        RefUpdate refUpdate,
        RefDatabase refDb,
        ImmutableSet<String> ignoredRefs);
  }

  /**
   * Constructs a {@code SharedRefDbRefUpdate} to create, update or delete a reference in project
   * projectName after validating the validity of the operation by an instance of {@code
   * RefUpdateValidator}, which is {@link Inject}ed by Guice.
   *
   * @param refValidatorFactory factory for {@link RefUpdateValidator}
   * @param projectName the name of the project being updated
   * @param refUpdate the wrapped ref update operation
   * @param refDb the mapping between refs and object ids
   * @param ignoredRefs a list of refs for which to ignore validation for.
   */
  @Inject
  public SharedRefDbRefUpdate(
      RefUpdateValidator.Factory refValidatorFactory,
      @Assisted String projectName,
      @Assisted RefUpdate refUpdate,
      @Assisted RefDatabase refDb,
      @Assisted ImmutableSet<String> ignoredRefs) {
    super(refUpdate.getRef());
    refUpdateBase = refUpdate;
    this.projectName = projectName;
    this.refValidatorFactory = refValidatorFactory;
    refUpdateValidator = this.refValidatorFactory.create(this.projectName, refDb, ignoredRefs);
  }

  @Override
  protected RefDatabase getRefDatabase() {
    return notImplementedException();
  }

  private <T> T notImplementedException() {
    throw new IllegalStateException("This method should have never been invoked");
  }

  @Override
  protected Repository getRepository() {
    return notImplementedException();
  }

  @Override
  protected boolean tryLock(boolean deref) throws IOException {
    return notImplementedException();
  }

  @Override
  protected void unlock() {
    notImplementedException();
  }

  @Override
  protected Result doUpdate(Result result) throws IOException {
    return notImplementedException();
  }

  @Override
  protected Result doDelete(Result result) throws IOException {
    return notImplementedException();
  }

  @Override
  protected Result doLink(String target) throws IOException {
    return notImplementedException();
  }

  /**
   * Update the ref to the new value, after checking its validity via {@link RefUpdateValidator}
   *
   * @return the result status of the update
   * @throws IOException an error occurred when attempting to write the change, either for an
   *     unexpected cause or because the validation failed and a split-brain was encountered or
   *     prevented.
   */
  @Override
  public Result update() throws IOException {
    return refUpdateValidator.executeRefUpdate(
        refUpdateBase,
        refUpdateBase::update,
        objectId -> rollback(objectId, refUpdateBase::update));
  }

  /**
   * Update the ref to the new value, after checking its validity via {@link RefUpdateValidator}
   *
   * @param rev a RevWalk instance this update command can borrow to perform the merge test. The
   *     walk will be reset to perform the test.
   * @return the result status of the update
   * @throws IOException an error occurred when attempting to write the change, either for an
   *     unexpected cause or because the validation failed and a split-brain was encountered or
   *     prevented.
   */
  @Override
  public Result update(RevWalk rev) throws IOException {
    return refUpdateValidator.executeRefUpdate(
        refUpdateBase,
        () -> refUpdateBase.update(rev),
        objectId -> rollback(objectId, () -> refUpdateBase.update(rev)));
  }

  /**
   * Delete the ref after checking its validity via {@link RefUpdateValidator}
   *
   * @return the result status of the delete
   * @throws IOException an error occurred when attempting to write the change, either for an
   *     unexpected cause or because the validation failed and a split-brain was encountered or
   *     prevented.
   */
  @Override
  public Result delete() throws IOException {
    return refUpdateValidator.executeRefUpdate(
        refUpdateBase,
        refUpdateBase::delete,
        objectId -> rollback(objectId, refUpdateBase::update));
  }

  /**
   * Delete the ref after checking its validity via {@link RefUpdateValidator}
   *
   * @param walk a RevWalk instance this delete command can borrow to perform the merge test. The
   *     walk will be reset to perform the test.
   * @return the result status of the delete
   * @throws IOException deletion failed
   */
  @Override
  public Result delete(RevWalk walk) throws IOException {
    return refUpdateValidator.executeRefUpdate(
        refUpdateBase,
        () -> refUpdateBase.delete(walk),
        objectId -> rollback(objectId, () -> refUpdateBase.update(walk)));
  }

  @Override
  public int hashCode() {
    return refUpdateBase.hashCode();
  }

  @Override
  public boolean equals(Object obj) {
    return refUpdateBase.equals(obj);
  }

  @Override
  public String toString() {
    return refUpdateBase.toString();
  }

  @Override
  public String getName() {
    return refUpdateBase.getName();
  }

  @Override
  public Ref getRef() {
    return refUpdateBase.getRef();
  }

  @Override
  public ObjectId getNewObjectId() {
    return refUpdateBase.getNewObjectId();
  }

  @Override
  public void setDetachingSymbolicRef() {
    refUpdateBase.setDetachingSymbolicRef();
  }

  @Override
  public boolean isDetachingSymbolicRef() {
    return refUpdateBase.isDetachingSymbolicRef();
  }

  @Override
  public void setNewObjectId(AnyObjectId id) {
    refUpdateBase.setNewObjectId(id);
  }

  @Override
  public ObjectId getExpectedOldObjectId() {
    return refUpdateBase.getExpectedOldObjectId();
  }

  @Override
  public void setExpectedOldObjectId(AnyObjectId id) {
    refUpdateBase.setExpectedOldObjectId(id);
  }

  @Override
  public boolean isForceUpdate() {
    return refUpdateBase.isForceUpdate();
  }

  @Override
  public void setForceUpdate(boolean b) {
    refUpdateBase.setForceUpdate(b);
  }

  @Override
  public PersonIdent getRefLogIdent() {
    return refUpdateBase.getRefLogIdent();
  }

  @Override
  public void setRefLogIdent(PersonIdent pi) {
    refUpdateBase.setRefLogIdent(pi);
  }

  @Override
  public String getRefLogMessage() {
    return refUpdateBase.getRefLogMessage();
  }

  @Override
  public void setRefLogMessage(String msg, boolean appendStatus) {
    refUpdateBase.setRefLogMessage(msg, appendStatus);
  }

  @Override
  public void disableRefLog() {
    refUpdateBase.disableRefLog();
  }

  @Override
  public void setForceRefLog(boolean force) {
    refUpdateBase.setForceRefLog(force);
  }

  @Override
  public ObjectId getOldObjectId() {
    return refUpdateBase.getOldObjectId();
  }

  @Override
  public void setPushCertificate(PushCertificate cert) {
    refUpdateBase.setPushCertificate(cert);
  }

  @Override
  public Result getResult() {
    return refUpdateBase.getResult();
  }

  @Override
  public Result forceUpdate() throws IOException {
    return refUpdateValidator.executeRefUpdate(
        refUpdateBase,
        refUpdateBase::forceUpdate,
        objectId -> rollback(objectId, refUpdateBase::forceUpdate));
  }

  @Override
  public Result link(String target) throws IOException {
    return refUpdateBase.link(target);
  }

  @Override
  public void setCheckConflicting(boolean check) {
    refUpdateBase.setCheckConflicting(check);
  }

  private Result rollback(ObjectId objectId, NoParameterFunction<Result> updateFunction)
      throws IOException {
    refUpdateBase.setExpectedOldObjectId(refUpdateBase.getNewObjectId());
    refUpdateBase.setNewObjectId(objectId);
    return updateFunction.invoke();
  }
}
