// Copyright (C) 2013 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.change;

import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.extensions.restapi.Response;
import com.google.gerrit.extensions.restapi.RestModifyView;
import com.google.gerrit.extensions.webui.UiAction;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.PatchSetInfo;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.change.DeleteDraftPatchSet.Input;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.patch.PatchSetInfoFactory;
import com.google.gerrit.server.patch.PatchSetInfoNotAvailableException;
import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gwtorm.server.AtomicUpdate;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;

import org.eclipse.jgit.lib.Config;

import java.io.IOException;

public class DeleteDraftPatchSet implements RestModifyView<RevisionResource, Input>,
    UiAction<RevisionResource> {
  public static class Input {
  }

  protected final Provider<ReviewDb> dbProvider;
  private final PatchSetInfoFactory patchSetInfoFactory;
  private final ChangeUtil changeUtil;
  private final boolean allowDrafts;

  @Inject
  public DeleteDraftPatchSet(Provider<ReviewDb> dbProvider,
      PatchSetInfoFactory patchSetInfoFactory,
      ChangeUtil changeUtil,
      @GerritServerConfig Config cfg) {
    this.dbProvider = dbProvider;
    this.patchSetInfoFactory = patchSetInfoFactory;
    this.changeUtil = changeUtil;
    this.allowDrafts = cfg.getBoolean("change", "allowDrafts", true);
  }

  @Override
  public Response<?> apply(RevisionResource rsrc, Input input)
      throws AuthException, ResourceNotFoundException,
      ResourceConflictException, OrmException, IOException {
    PatchSet patchSet = rsrc.getPatchSet();
    PatchSet.Id patchSetId = patchSet.getId();
    Change change = rsrc.getChange();

    if (!patchSet.isDraft()) {
      throw new ResourceConflictException("Patch set is not a draft.");
    }

    if (!allowDrafts) {
      throw new ResourceConflictException("Draft workflow is disabled.");
    }

    if (!rsrc.getControl().canDeleteDraft(dbProvider.get())) {
      throw new AuthException("Not permitted to delete this draft patch set");
    }

    deleteDraftPatchSet(patchSet, change);
    deleteOrUpdateDraftChange(patchSetId, change);

    return Response.none();
  }

  @Override
  public UiAction.Description getDescription(RevisionResource rsrc) {
    try {
      int psCount = dbProvider.get().patchSets()
          .byChange(rsrc.getChange().getId()).toList().size();
      return new UiAction.Description()
        .setTitle(String.format("Delete draft revision %d",
            rsrc.getPatchSet().getPatchSetId()))
        .setVisible(allowDrafts
            && rsrc.getPatchSet().isDraft()
            && rsrc.getControl().canDeleteDraft(dbProvider.get())
            && psCount > 1);
    } catch (OrmException e) {
      throw new IllegalStateException(e);
    }
  }

  private void deleteDraftPatchSet(PatchSet patchSet, Change change)
      throws ResourceNotFoundException, OrmException, IOException {
    try {
      changeUtil.deleteOnlyDraftPatchSet(patchSet, change);
    } catch (NoSuchChangeException e) {
      throw new ResourceNotFoundException(e.getMessage());
    }
  }

  private void deleteOrUpdateDraftChange(PatchSet.Id patchSetId,
      Change change) throws OrmException, ResourceNotFoundException,
      IOException {
    if (dbProvider.get()
            .patchSets()
            .byChange(change.getId())
            .toList().size() == 0) {
      deleteDraftChange(patchSetId);
    } else {
      if (change.currentPatchSetId().equals(patchSetId)) {
        updateChange(dbProvider.get(), change,
            previousPatchSetInfo(patchSetId));
      } else {
        // TODO(davido): find a better way to enforce cache invalidation.
        updateChange(dbProvider.get(), change, null);
      }
    }
  }

  private void deleteDraftChange(PatchSet.Id patchSetId)
      throws OrmException, IOException, ResourceNotFoundException {
    try {
      changeUtil.deleteDraftChange(patchSetId);
    } catch (NoSuchChangeException e) {
      throw new ResourceNotFoundException(e.getMessage());
    }
  }

  private PatchSetInfo previousPatchSetInfo(PatchSet.Id patchSetId)
      throws ResourceNotFoundException {
    try {
      return patchSetInfoFactory.get(dbProvider.get(),
          new PatchSet.Id(patchSetId.getParentKey(),
              patchSetId.get() - 1));
    } catch (PatchSetInfoNotAvailableException e) {
        throw new ResourceNotFoundException(e.getMessage());
    }
  }

  private static void updateChange(final ReviewDb db,
      final Change change, final PatchSetInfo psInfo)
      throws OrmException {
    db.changes().atomicUpdate(change.getId(), new AtomicUpdate<Change>() {
      @Override
      public Change update(Change c) {
        if (psInfo != null) {
          c.setCurrentPatchSet(psInfo);
        }
        ChangeUtil.updated(c);
        return c;
      }
    });
  }
}
