// Copyright (C) 2016 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.acceptance.rest.project;

import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.acceptance.GitUtil.createAnnotatedTag;
import static com.google.gerrit.acceptance.GitUtil.deleteRef;
import static com.google.gerrit.acceptance.GitUtil.pushHead;
import static com.google.gerrit.acceptance.GitUtil.updateAnnotatedTag;
import static com.google.gerrit.acceptance.rest.project.PushTagIT.TagType.ANNOTATED;
import static com.google.gerrit.acceptance.rest.project.PushTagIT.TagType.LIGHTWEIGHT;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;

import com.google.common.base.MoreObjects;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.GitUtil;
import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.reviewdb.client.RefNames;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.transport.PushResult;
import org.eclipse.jgit.transport.RemoteRefUpdate;
import org.eclipse.jgit.transport.RemoteRefUpdate.Status;
import org.junit.Before;
import org.junit.Test;

@NoHttpd
public class PushTagIT extends AbstractDaemonTest {
  enum TagType {
    LIGHTWEIGHT(Permission.CREATE),
    ANNOTATED(Permission.CREATE_TAG);

    final String createPermission;

    TagType(String createPermission) {
      this.createPermission = createPermission;
    }
  }

  private RevCommit initialHead;

  @Before
  public void setup() throws Exception {
    // clone with user to avoid inherited tag permissions of admin user
    testRepo = cloneProject(project, user);

    initialHead = getRemoteHead();
  }

  @Test
  public void createTagForExistingCommit() throws Exception {
    for (TagType tagType : TagType.values()) {
      pushTagForExistingCommit(tagType, Status.REJECTED_OTHER_REASON);

      allowTagCreation(tagType);
      pushTagForExistingCommit(tagType, Status.OK);

      allowPushOnRefsTags();
      pushTagForExistingCommit(tagType, Status.OK);

      removePushFromRefsTags();
    }
  }

  @Test
  public void createTagForNewCommit() throws Exception {
    for (TagType tagType : TagType.values()) {
      pushTagForNewCommit(tagType, Status.REJECTED_OTHER_REASON);

      allowTagCreation(tagType);
      pushTagForNewCommit(tagType, Status.REJECTED_OTHER_REASON);

      allowPushOnRefsTags();
      pushTagForNewCommit(tagType, Status.OK);

      removePushFromRefsTags();
    }
  }

  @Test
  public void fastForward() throws Exception {
    for (TagType tagType : TagType.values()) {
      allowTagCreation(tagType);
      String tagName = pushTagForExistingCommit(tagType, Status.OK);

      fastForwardTagToExistingCommit(tagType, tagName, Status.REJECTED_OTHER_REASON);
      fastForwardTagToNewCommit(tagType, tagName, Status.REJECTED_OTHER_REASON);

      allowTagDeletion();
      fastForwardTagToExistingCommit(tagType, tagName, Status.REJECTED_OTHER_REASON);
      fastForwardTagToNewCommit(tagType, tagName, Status.REJECTED_OTHER_REASON);

      allowPushOnRefsTags();
      Status expectedStatus = tagType == ANNOTATED ? Status.REJECTED_OTHER_REASON : Status.OK;
      fastForwardTagToExistingCommit(tagType, tagName, expectedStatus);
      fastForwardTagToNewCommit(tagType, tagName, expectedStatus);

      allowForcePushOnRefsTags();
      fastForwardTagToExistingCommit(tagType, tagName, Status.OK);
      fastForwardTagToNewCommit(tagType, tagName, Status.OK);

      removePushFromRefsTags();
    }
  }

  @Test
  public void forceUpdate() throws Exception {
    for (TagType tagType : TagType.values()) {
      allowTagCreation(tagType);
      String tagName = pushTagForExistingCommit(tagType, Status.OK);

      forceUpdateTagToExistingCommit(tagType, tagName, Status.REJECTED_OTHER_REASON);
      forceUpdateTagToNewCommit(tagType, tagName, Status.REJECTED_OTHER_REASON);

      allowPushOnRefsTags();
      forceUpdateTagToExistingCommit(tagType, tagName, Status.REJECTED_OTHER_REASON);
      forceUpdateTagToNewCommit(tagType, tagName, Status.REJECTED_OTHER_REASON);

      allowTagDeletion();
      forceUpdateTagToExistingCommit(tagType, tagName, Status.REJECTED_OTHER_REASON);
      forceUpdateTagToNewCommit(tagType, tagName, Status.REJECTED_OTHER_REASON);

      allowForcePushOnRefsTags();
      forceUpdateTagToExistingCommit(tagType, tagName, Status.OK);
      forceUpdateTagToNewCommit(tagType, tagName, Status.OK);

      removePushFromRefsTags();
    }
  }

  @Test
  public void delete() throws Exception {
    for (TagType tagType : TagType.values()) {
      allowTagCreation(tagType);
      String tagName = pushTagForExistingCommit(tagType, Status.OK);

      pushTagDeletion(tagType, tagName, Status.REJECTED_OTHER_REASON);

      allowPushOnRefsTags();
      pushTagDeletion(tagType, tagName, Status.REJECTED_OTHER_REASON);
    }

    allowForcePushOnRefsTags();
    for (TagType tagType : TagType.values()) {
      String tagName = pushTagForExistingCommit(tagType, Status.OK);
      pushTagDeletion(tagType, tagName, Status.OK);
    }

    removePushFromRefsTags();
    allowTagDeletion();
    for (TagType tagType : TagType.values()) {
      String tagName = pushTagForExistingCommit(tagType, Status.OK);
      pushTagDeletion(tagType, tagName, Status.OK);
    }
  }

  private String pushTagForExistingCommit(TagType tagType, Status expectedStatus) throws Exception {
    return pushTag(tagType, null, false, false, expectedStatus);
  }

  private String pushTagForNewCommit(TagType tagType, Status expectedStatus) throws Exception {
    return pushTag(tagType, null, true, false, expectedStatus);
  }

  private void fastForwardTagToExistingCommit(
      TagType tagType, String tagName, Status expectedStatus) throws Exception {
    pushTag(tagType, tagName, false, false, expectedStatus);
  }

  private void fastForwardTagToNewCommit(TagType tagType, String tagName, Status expectedStatus)
      throws Exception {
    pushTag(tagType, tagName, true, false, expectedStatus);
  }

  private void forceUpdateTagToExistingCommit(
      TagType tagType, String tagName, Status expectedStatus) throws Exception {
    pushTag(tagType, tagName, false, true, expectedStatus);
  }

  private void forceUpdateTagToNewCommit(TagType tagType, String tagName, Status expectedStatus)
      throws Exception {
    pushTag(tagType, tagName, true, true, expectedStatus);
  }

  private String pushTag(
      TagType tagType, String tagName, boolean newCommit, boolean force, Status expectedStatus)
      throws Exception {
    if (force) {
      testRepo.reset(initialHead);
    }
    commit(user.getIdent(), "subject");

    boolean createTag = tagName == null;
    tagName = MoreObjects.firstNonNull(tagName, "v1_" + System.nanoTime());
    switch (tagType) {
      case LIGHTWEIGHT:
        break;
      case ANNOTATED:
        if (createTag) {
          createAnnotatedTag(testRepo, tagName, user.getIdent());
        } else {
          updateAnnotatedTag(testRepo, tagName, user.getIdent());
        }
        break;
      default:
        throw new IllegalStateException("unexpected tag type: " + tagType);
    }

    if (!newCommit) {
      grant(Permission.SUBMIT, project, "refs/for/refs/heads/master", false, REGISTERED_USERS);
      pushHead(testRepo, "refs/for/master%submit");
    }

    String tagRef = tagRef(tagName);
    PushResult r =
        tagType == LIGHTWEIGHT
            ? pushHead(testRepo, tagRef, false, force)
            : GitUtil.pushTag(testRepo, tagName, !createTag);
    RemoteRefUpdate refUpdate = r.getRemoteUpdate(tagRef);
    assertThat(refUpdate.getStatus()).named(tagType.name()).isEqualTo(expectedStatus);
    return tagName;
  }

  private void pushTagDeletion(TagType tagType, String tagName, Status expectedStatus)
      throws Exception {
    String tagRef = tagRef(tagName);
    PushResult r = deleteRef(testRepo, tagRef);
    RemoteRefUpdate refUpdate = r.getRemoteUpdate(tagRef);
    assertThat(refUpdate.getStatus()).named(tagType.name()).isEqualTo(expectedStatus);
  }

  private void allowTagCreation(TagType tagType) throws Exception {
    grant(tagType.createPermission, project, "refs/tags/*", false, REGISTERED_USERS);
  }

  private void allowPushOnRefsTags() throws Exception {
    removePushFromRefsTags();
    grant(Permission.PUSH, project, "refs/tags/*", false, REGISTERED_USERS);
  }

  private void allowForcePushOnRefsTags() throws Exception {
    removePushFromRefsTags();
    grant(Permission.PUSH, project, "refs/tags/*", true, REGISTERED_USERS);
  }

  private void allowTagDeletion() throws Exception {
    removePushFromRefsTags();
    grant(Permission.DELETE, project, "refs/tags/*", true, REGISTERED_USERS);
  }

  private void removePushFromRefsTags() throws Exception {
    removePermission(Permission.PUSH, project, "refs/tags/*");
  }

  private void commit(PersonIdent ident, String subject) throws Exception {
    commitBuilder().ident(ident).message(subject + " (" + System.nanoTime() + ")").create();
  }

  private static String tagRef(String tagName) {
    return RefNames.REFS_TAGS + tagName;
  }
}
