// 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.ericsson.gerrit.plugins.projectgroupstructure;

import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;

import com.google.common.base.Charsets;
import com.google.common.collect.Lists;
import com.google.common.hash.Hashing;
import com.google.gerrit.acceptance.LightweightPluginDaemonTest;
import com.google.gerrit.acceptance.RestResponse;
import com.google.gerrit.acceptance.TestPlugin;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.common.data.GroupReference;
import com.google.gerrit.extensions.api.groups.GroupApi;
import com.google.gerrit.extensions.api.projects.ProjectInput;
import com.google.gerrit.extensions.restapi.Url;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.project.ProjectConfig;
import com.google.gerrit.server.project.ProjectState;
import org.junit.Before;
import org.junit.Test;

@TestPlugin(
    name = "project-group-structure",
    sysModule = "com.ericsson.gerrit.plugins.projectgroupstructure.Module")
public class ProjectCreationValidatorIT extends LightweightPluginDaemonTest {

  private static final String PLUGIN_NAME = "project-group-structure";

  @Override
  @Before
  public void setUpTestPlugin() throws Exception {
    super.setUpTestPlugin();
    // These access rights are mandatory configuration for this plugin as
    // documented in config.md
    allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.CREATE_GROUP);
    allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.CREATE_PROJECT);
  }

  @Test
  public void shouldProjectWithASpaceInTheirName() throws Exception {
    ProjectInput in = new ProjectInput();
    in.permissionsOnly = true;
    RestResponse r = userRestSession.put("/projects/" + Url.encode("project with space"), in);
    r.assertConflict();
    assertThat(r.getEntityContent()).contains("Project name cannot contains spaces");
  }

  @Test
  public void shouldAllowAnyUsersToCreateUnderAllProjects() throws Exception {
    ProjectInput in = new ProjectInput();
    in.permissionsOnly = true;
    adminRestSession.put("/projects/" + name("someProject"), in).assertCreated();

    userRestSession.put("/projects/" + name("someOtherProject"), in).assertCreated();
  }

  @Test
  public void shouldBlockRootProjectWithSlashesInTheirName() throws Exception {
    // Root project is OK without slash
    String parent = name("parentProject");
    ProjectInput in = new ProjectInput();
    in.permissionsOnly = true;
    userRestSession.put("/projects/" + parent, in).assertCreated();

    // Creation is rejected when root project name contains slashes
    RestResponse r = userRestSession.put("/projects/" + Url.encode("a/parentProject"), in);
    r.assertConflict();
    assertThat(r.getEntityContent()).contains("Root project names cannot contain slashes");
  }

  @Test
  public void shouldBlockProjectWithParentNotPartOfProjectName() throws Exception {
    // Root project is OK without parent part of the name
    ProjectInput in = new ProjectInput();
    in.permissionsOnly = true;
    String parent = name("parentProject");
    userRestSession.put("/projects/" + parent, in).assertCreated();

    // Creation is rejected when project name does not start with parent
    in = new ProjectInput();
    in.parent = parent;
    RestResponse r = userRestSession.put("/projects/childProject", in);
    r.assertConflict();
    assertThat(r.getEntityContent()).contains("Project name must start with parent project name");

    // Creation is OK when project name starts with parent
    userRestSession.put("/projects/" + Url.encode(parent + "/childProject"), in).assertCreated();

    // Creation is rejected when project name does not start with nested parent
    String nestedParent = parent + "/childProject";
    in.parent = nestedParent;
    r = userRestSession.put("/projects/grandchild", in);
    r.assertConflict();
    assertThat(r.getEntityContent()).contains("Project name must start with parent project name");

    // Creation is OK when project name starts with nested parent
    userRestSession
        .put("/projects/" + Url.encode(nestedParent + "/grandchild"), in)
        .assertCreated();
  }

  @Test
  public void shouldBlockCreationToNonOwnersOfParentProject() throws Exception {
    String ownerGroup = name("groupA");
    GroupApi g = gApi.groups().create(ownerGroup);

    String parent = name("parentProject");
    ProjectInput in = new ProjectInput();
    in.permissionsOnly = true;
    in.owners = Lists.newArrayList(ownerGroup);
    adminRestSession.put("/projects/" + parent, in).assertCreated();

    // Creation is rejected when user is not owner of parent
    in = new ProjectInput();
    in.parent = parent;
    RestResponse r = userRestSession.put("/projects/" + Url.encode(parent + "/childProject"), in);
    r.assertConflict();
    assertThat(r.getEntityContent()).contains("You must be owner of the parent project");

    // Creation is OK when user is owner of parent
    g.addMembers(user.username());
    userRestSession.put("/projects/" + Url.encode(parent + "/childProject"), in).assertCreated();
  }

  @Test
  public void shouldAllowAdminsToByPassAnyRule() throws Exception {
    // Root project with a slash
    String parent = name("orgA/parentProject");
    ProjectInput in = new ProjectInput();
    in.permissionsOnly = true;
    adminRestSession.put("/projects/" + Url.encode(parent), in).assertCreated();

    // Child project without name of parent as prefix
    in = new ProjectInput();
    in.parent = parent;
    adminRestSession.put("/projects/" + Url.encode("orgA/childProject"), in).assertCreated();
  }

  @Test
  public void shouldMakeUserOwnerOnRootProjectCreation() throws Exception {
    // normal case, when <project-name>-admins group does not exist
    String rootProject = name("rootProject");
    ProjectInput in = new ProjectInput();
    in.permissionsOnly = true;
    userRestSession.put("/projects/" + rootProject, in).assertCreated();
    ProjectState projectState = projectCache.get(new Project.NameKey(rootProject));
    assertThat(projectState.getOwners().size()).isEqualTo(1);
    assertThat(projectState.getOwners())
        .contains(
            groupCache.get(new AccountGroup.NameKey(rootProject + "-admins")).get().getGroupUUID());

    // case when <project-name>-admins group already exists
    rootProject = name("rootProject2");
    String existingGroupName = rootProject + "-admins";
    gApi.groups().create(existingGroupName);
    userRestSession.put("/projects/" + rootProject, in).assertCreated();
    projectState = projectCache.get(new Project.NameKey(rootProject));
    assertThat(projectState.getOwners().size()).isEqualTo(1);
    String expectedOwnerGroup =
        existingGroupName
            + "-"
            + Hashing.sha256()
                .hashString(existingGroupName, Charsets.UTF_8)
                .toString()
                .substring(0, 7);
    assertThat(projectState.getOwners())
        .contains(
            groupCache.get(new AccountGroup.NameKey(expectedOwnerGroup)).get().getGroupUUID());
  }

  @Test
  public void shouldBlockRootCodeProject() throws Exception {
    RestResponse r = userRestSession.put("/projects/" + Url.encode("project1"));
    r.assertConflict();
    assertThat(r.getEntityContent()).contains("Regular projects are not allowed as root");
  }

  @Test
  public void shouldAllowCreationIfUserIsInDelegatingGroup() throws Exception {
    String ownerGroup = name("groupA");
    gApi.groups().create(ownerGroup);

    String parent = name("parentProject");
    ProjectInput in = new ProjectInput();
    in.permissionsOnly = true;
    in.owners = Lists.newArrayList(ownerGroup);
    adminRestSession.put("/projects/" + parent, in).assertCreated();

    in = new ProjectInput();
    in.parent = parent;
    RestResponse r = userRestSession.put("/projects/" + Url.encode(parent + "/childProject"), in);
    r.assertConflict();
    assertThat(r.getEntityContent()).contains("You must be owner of the parent project");

    // the user is in the delegating group
    String delegatingGroup = name("groupB");
    GroupApi dGroup = gApi.groups().create(delegatingGroup);
    dGroup.addMembers(user.username());
    // the group is in the project.config
    Project.NameKey parentNameKey = new Project.NameKey(parent);
    try (ProjectConfigUpdate cfgUpdate = updateProject(parentNameKey)) {
      ProjectConfig cfg = cfgUpdate.getConfig();
      String gId = gApi.groups().id(delegatingGroup).get().id;
      cfg.getPluginConfig(PLUGIN_NAME)
          .setGroupReference(
              ProjectCreationValidator.DELEGATE_PROJECT_CREATION_TO,
              new GroupReference(AccountGroup.UUID.parse(gId), delegatingGroup));
      cfgUpdate.save();
    }
    userRestSession.put("/projects/" + Url.encode(parent + "/childProject"), in).assertCreated();
  }

  @Test
  public void shouldMakeUserOwnerIfNotAlreadyOwnerByInheritance() throws Exception {
    String parent = name("parentProject");
    ProjectInput in = new ProjectInput();
    in.permissionsOnly = true;
    adminRestSession.put("/projects/" + parent, in).assertCreated();

    String delegatingGroup = name("someGroup");
    GroupApi dGroup = gApi.groups().create(delegatingGroup);
    dGroup.addMembers(user.username());
    Project.NameKey parentNameKey = new Project.NameKey(parent);
    try (ProjectConfigUpdate cfgUpdate = updateProject(parentNameKey)) {
      ProjectConfig cfg = cfgUpdate.getConfig();
      String gId = gApi.groups().id(delegatingGroup).get().id;
      cfg.getPluginConfig(PLUGIN_NAME)
          .setGroupReference(
              ProjectCreationValidator.DELEGATE_PROJECT_CREATION_TO,
              new GroupReference(AccountGroup.UUID.parse(gId), delegatingGroup));
      cfgUpdate.save();
    }

    // normal case, when <project-name>-admins group does not exist
    in = new ProjectInput();
    in.parent = parent;
    String childProject = parent + "/childProject";
    userRestSession.put("/projects/" + Url.encode(childProject), in).assertCreated();
    ProjectState projectState = projectCache.get(new Project.NameKey(childProject));
    assertThat(projectState.getOwners().size()).isEqualTo(1);
    assertThat(projectState.getOwners())
        .contains(
            groupCache
                .get(new AccountGroup.NameKey(childProject + "-admins"))
                .get()
                .getGroupUUID());

    // case when <project-name>-admins group already exists
    String childProject2 = parent + "/childProject2";
    String existingGroupName = childProject2 + "-admins";
    gApi.groups().create(existingGroupName);
    userRestSession.put("/projects/" + Url.encode(childProject2), in).assertCreated();
    projectState = projectCache.get(new Project.NameKey(childProject2));
    assertThat(projectState.getOwners().size()).isEqualTo(1);
    String expectedOwnerGroup =
        existingGroupName
            + "-"
            + Hashing.sha256()
                .hashString(existingGroupName, Charsets.UTF_8)
                .toString()
                .substring(0, 7);
    assertThat(projectState.getOwners())
        .contains(
            groupCache.get(new AccountGroup.NameKey(expectedOwnerGroup)).get().getGroupUUID());
  }

  @Test
  public void shouldNotMakeUserOwnerIfNotAlreadyOwnerByInheritanceAndGrantingIsDisabled()
      throws Exception {
    String parent = name("parentProject");
    ProjectInput in = new ProjectInput();
    in.permissionsOnly = true;
    adminRestSession.put("/projects/" + parent, in).assertCreated();

    String delegatingGroup = name("someGroup");
    GroupApi dGroup = gApi.groups().create(delegatingGroup);
    dGroup.addMembers(user.username());
    Project.NameKey parentNameKey = new Project.NameKey(parent);
    try (ProjectConfigUpdate cfgUpdate = updateProject(parentNameKey)) {
      ProjectConfig cfg = cfgUpdate.getConfig();
      String gId = gApi.groups().id(delegatingGroup).get().id;
      cfg.getPluginConfig(PLUGIN_NAME)
          .setGroupReference(
              ProjectCreationValidator.DELEGATE_PROJECT_CREATION_TO,
              new GroupReference(AccountGroup.UUID.parse(gId), delegatingGroup));
      cfg.getPluginConfig(PLUGIN_NAME)
          .setBoolean(ProjectCreationValidator.DISABLE_GRANTING_PROJECT_OWNERSHIP, true);
      cfgUpdate.save();
    }

    in = new ProjectInput();
    in.parent = parent;
    String childProject = parent + "/childProject";
    userRestSession.put("/projects/" + Url.encode(childProject), in).assertCreated();
    ProjectState projectState = projectCache.get(new Project.NameKey(childProject));
    assertThat(projectState.getOwners().size()).isEqualTo(0);
  }

  @Test
  public void shouldBlockCreationIfGroupRefIsNotUsed() throws Exception {
    String ownerGroup = name("groupA");
    gApi.groups().create(ownerGroup);

    String parent = name("parentProject");
    ProjectInput in = new ProjectInput();
    in.permissionsOnly = true;
    in.owners = Lists.newArrayList(ownerGroup);
    adminRestSession.put("/projects/" + parent, in).assertCreated();

    in = new ProjectInput();
    in.parent = parent;
    RestResponse r = userRestSession.put("/projects/" + Url.encode(parent + "/childProject"), in);
    r.assertConflict();
    assertThat(r.getEntityContent()).contains("You must be owner of the parent project");

    // the user is in the delegating group
    String delegatingGroup = name("groupB");
    GroupApi dGroup = gApi.groups().create(delegatingGroup);
    dGroup.addMembers(user.username());
    // the group is in the project.config
    Project.NameKey parentNameKey = new Project.NameKey(parent);
    try (ProjectConfigUpdate cfgUpdate = updateProject(parentNameKey)) {
      ProjectConfig cfg = cfgUpdate.getConfig();
      cfg.getPluginConfig(PLUGIN_NAME)
          .setString(ProjectCreationValidator.DELEGATE_PROJECT_CREATION_TO, delegatingGroup);
      cfgUpdate.save();
    }
    userRestSession.put("/projects/" + Url.encode(parent + "/childProject"), in).assertConflict();
  }

  @Test
  public void shouldAllowCreationIfUserIsInDelegatingGroupNested() throws Exception {
    String ownerGroup = name("groupA");
    gApi.groups().create(ownerGroup);

    String parent = name("parentProject");
    ProjectInput in = new ProjectInput();
    in.permissionsOnly = true;
    in.owners = Lists.newArrayList(ownerGroup);
    adminRestSession.put("/projects/" + parent, in).assertCreated();

    in = new ProjectInput();
    in.parent = parent;
    RestResponse r = userRestSession.put("/projects/" + Url.encode(parent + "/childProject"), in);
    r.assertConflict();
    assertThat(r.getEntityContent()).contains("You must be owner of the parent project");

    // the user is in the nested delegating group
    String delegatingGroup = name("groupB");
    GroupApi dGroup = gApi.groups().create(delegatingGroup);

    String nestedGroup = name("groupC");
    GroupApi nGroup = gApi.groups().create(nestedGroup);
    nGroup.addMembers(user.username());

    dGroup.addGroups(nestedGroup);
    // the group is in the project.config
    Project.NameKey parentNameKey = new Project.NameKey(parent);
    try (ProjectConfigUpdate cfgUpdate = updateProject(parentNameKey)) {
      ProjectConfig cfg = cfgUpdate.getConfig();
      String gId = gApi.groups().id(delegatingGroup).get().id;
      cfg.getPluginConfig(PLUGIN_NAME)
          .setGroupReference(
              ProjectCreationValidator.DELEGATE_PROJECT_CREATION_TO,
              new GroupReference(AccountGroup.UUID.parse(gId), delegatingGroup));
      cfgUpdate.save();
    }
    userRestSession.put("/projects/" + Url.encode(parent + "/childProject"), in).assertCreated();
  }

  @Test
  public void shouldBlockCreationIfUserIsNotInDelegatingGroup() throws Exception {
    String ownerGroup = name("groupA");
    gApi.groups().create(ownerGroup);

    String parent = name("parentProject");
    ProjectInput in = new ProjectInput();
    in.permissionsOnly = true;
    in.owners = Lists.newArrayList(ownerGroup);
    adminRestSession.put("/projects/" + parent, in).assertCreated();

    in = new ProjectInput();
    in.parent = parent;
    RestResponse r = userRestSession.put("/projects/" + Url.encode(parent + "/childProject"), in);
    r.assertConflict();
    assertThat(r.getEntityContent()).contains("You must be owner of the parent project");

    // the user is in the delegating group
    String delegatingGroup = name("groupB");
    gApi.groups().create(delegatingGroup);
    // The user is not added to the delegated group
    // the group is in the project.config
    Project.NameKey parentNameKey = new Project.NameKey(parent);
    try (ProjectConfigUpdate cfgUpdate = updateProject(parentNameKey)) {
      ProjectConfig cfg = cfgUpdate.getConfig();
      String gId = gApi.groups().id(delegatingGroup).get().id;
      cfg.getPluginConfig(PLUGIN_NAME)
          .setGroupReference(
              ProjectCreationValidator.DELEGATE_PROJECT_CREATION_TO,
              new GroupReference(AccountGroup.UUID.parse(gId), delegatingGroup));
      cfgUpdate.save();
    }
    userRestSession.put("/projects/" + Url.encode(parent + "/childProject"), in).assertConflict();
  }

  @Test
  public void shouldBlockCreationIfDelegatingGroupDoesNotExist() throws Exception {
    String ownerGroup = name("groupA");
    gApi.groups().create(ownerGroup);

    String parent = name("parentProject");
    ProjectInput in = new ProjectInput();
    in.permissionsOnly = true;
    in.owners = Lists.newArrayList(ownerGroup);
    adminRestSession.put("/projects/" + parent, in).assertCreated();

    in = new ProjectInput();
    in.parent = parent;
    RestResponse r = userRestSession.put("/projects/" + Url.encode(parent + "/childProject"), in);
    r.assertConflict();
    assertThat(r.getEntityContent()).contains("You must be owner of the parent project");

    // The delegating group is not created
    String delegatingGroup = name("groupB");
    // the group is in the project.config
    Project.NameKey parentNameKey = new Project.NameKey(parent);
    try (ProjectConfigUpdate cfgUpdate = updateProject(parentNameKey)) {
      ProjectConfig cfg = cfgUpdate.getConfig();
      String gId = "fake-gId";
      cfg.getPluginConfig(PLUGIN_NAME)
          .setGroupReference(
              ProjectCreationValidator.DELEGATE_PROJECT_CREATION_TO,
              new GroupReference(AccountGroup.UUID.parse(gId), delegatingGroup));
      cfgUpdate.save();
    }
    userRestSession.put("/projects/" + Url.encode(parent + "/childProject"), in).assertConflict();
  }

  @Test
  public void shouldNotBlockCreationIfDelegatingGroupIsRenamed() throws Exception {
    String ownerGroup = name("groupA");
    gApi.groups().create(ownerGroup);

    String parent = name("parentProject");
    ProjectInput in = new ProjectInput();
    in.permissionsOnly = true;
    in.owners = Lists.newArrayList(ownerGroup);
    adminRestSession.put("/projects/" + parent, in).assertCreated();

    in = new ProjectInput();
    in.parent = parent;
    RestResponse r = userRestSession.put("/projects/" + Url.encode(parent + "/childProject"), in);
    r.assertConflict();
    assertThat(r.getEntityContent()).contains("You must be owner of the parent project");

    // the user is in the delegating group
    String delegatingGroup = name("groupB");
    GroupApi dGroup = gApi.groups().create(delegatingGroup);
    dGroup.addMembers(user.username());
    // the group is in the project.config
    Project.NameKey parentNameKey = new Project.NameKey(parent);
    try (ProjectConfigUpdate cfgUpdate = updateProject(parentNameKey)) {
      ProjectConfig cfg = cfgUpdate.getConfig();

      String gId = gApi.groups().id(delegatingGroup).get().id;
      cfg.getPluginConfig("project-group-structure")
          .setGroupReference(
              ProjectCreationValidator.DELEGATE_PROJECT_CREATION_TO,
              new GroupReference(AccountGroup.UUID.parse(gId), delegatingGroup));
      cfgUpdate.save();
    }

    String newDelegatingGroup = name("groupC");
    gApi.groups().id(delegatingGroup).name(newDelegatingGroup);

    userRestSession.put("/projects/" + Url.encode(parent + "/childProject"), in).assertCreated();
  }
}
