// 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.dfsrefdb;

import java.io.IOException;
import org.apache.commons.lang.NotImplementedException;
import org.eclipse.jgit.lib.ObjectId;
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.junit.Ignore;

@Ignore
public class RefUpdateStub extends RefUpdate {

  public static RefUpdate forSuccessfulCreate(Ref newRef) {
    return new RefUpdateStub(Result.NEW, null, newRef, newRef.getObjectId());
  }

  public static RefUpdate forSuccessfulUpdate(Ref oldRef, ObjectId newObjectId) {
    return new RefUpdateStub(Result.FAST_FORWARD, null, oldRef, newObjectId);
  }

  public static RefUpdate forSuccessfulDelete(Ref oldRef) {
    return new RefUpdateStub(null, Result.FORCED, oldRef, ObjectId.zeroId());
  }

  private final Result updateResult;
  private final Result deleteResult;

  public RefUpdateStub(Result updateResult, Result deleteResult, Ref oldRef, ObjectId newObjectId) {
    super(oldRef);
    this.setNewObjectId(newObjectId);
    this.updateResult = updateResult;
    this.deleteResult = deleteResult;
  }

  @Override
  protected RefDatabase getRefDatabase() {
    throw new NotImplementedException("Method not implemented yet, not assumed you needed it!!");
  }

  @Override
  protected Repository getRepository() {
    throw new NotImplementedException("Method not implemented yet, not assumed you needed it!!");
  }

  @Override
  protected boolean tryLock(boolean deref) throws IOException {
    throw new NotImplementedException("Method not implemented yet, not assumed you needed it!!");
  }

  @Override
  protected void unlock() {
    throw new NotImplementedException("Method not implemented yet, not assumed you needed it!!");
  }

  @Override
  protected Result doUpdate(Result desiredResult) throws IOException {
    throw new NotImplementedException("Method not implemented, shouldn't be called!!");
  }

  @Override
  protected Result doDelete(Result desiredResult) throws IOException {
    throw new NotImplementedException("Method not implemented, shouldn't be called!!");
  }

  @Override
  protected Result doLink(String target) throws IOException {
    throw new NotImplementedException("Method not implemented yet, not assumed you needed it!!");
  }

  @Override
  public Result update() throws IOException {
    if (updateResult != null) return updateResult;

    throw new NotImplementedException("Not assumed you needed to stub this call!!");
  }

  @Override
  public Result update(RevWalk walk) throws IOException {
    if (updateResult != null) return updateResult;

    throw new NotImplementedException("Not assumed you needed to stub this call!!");
  }

  @Override
  public Result delete() throws IOException {
    if (deleteResult != null) return deleteResult;

    throw new NotImplementedException("Not assumed you needed to stub this call!!");
  }

  @Override
  public Result delete(RevWalk walk) throws IOException {
    if (deleteResult != null) return deleteResult;

    throw new NotImplementedException("Not assumed you needed to stub this call!!");
  }
}
