// Copyright (C) 2015 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.googlesource.gerrit.plugins.reparent;

import static com.googlesource.gerrit.plugins.reparent.ReparentOwnProjectCapability.REPARENT_OWN_PROJECT;
import static com.googlesource.gerrit.plugins.reparent.ReparentProjectCapability.REPARENT_PROJECT;

import com.google.common.base.Strings;
import com.google.gerrit.extensions.annotations.PluginName;
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.RestModifyView;
import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
import com.google.gerrit.extensions.webui.UiAction;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.account.CapabilityControl;
import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.config.PluginConfig;
import com.google.gerrit.server.config.PluginConfigFactory;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectResource;
import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.server.project.SetParent.Input;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

@Singleton
public class SetParent implements
    RestModifyView<ProjectResource, com.google.gerrit.server.project.SetParent.Input>,
    UiAction<ProjectResource>{
  private static final String KEY_JAIL = "jail";
  private static final String KEY_PROTECTORATE = "protectorate";

  private final String pluginName;
  private final Provider<CurrentUser> userProvider;
  private final AllProjectsName allProjectsName;
  private final PluginConfigFactory cfgFactory;
  private final ProjectCache projectCache;
  private final com.google.gerrit.server.project.SetParent setParent;

  @Inject
  SetParent(@PluginName String pluginName,
      Provider<CurrentUser> userProvider,
      AllProjectsName allProjectsName,
      PluginConfigFactory cfgFactory,
      ProjectCache projectCache,
      com.google.gerrit.server.project.SetParent setParent) {
    this.pluginName = pluginName;
    this.userProvider = userProvider;
    this.allProjectsName = allProjectsName;
    this.cfgFactory = cfgFactory;
    this.projectCache = projectCache;
    this.setParent = setParent;
  }

  @Override
  public Object apply(ProjectResource rsrc, Input input) throws AuthException,
      ResourceConflictException, ResourceNotFoundException,
      UnprocessableEntityException, IOException {
    assertReparentPermission(rsrc);
    ProjectState newParent = getNewParentProject(input);
    assertReparent(rsrc, newParent);
    return setParent.apply(rsrc, input, false);
  }

  private void assertReparent(ProjectResource rsrc, ProjectState newParent)
      throws ResourceConflictException {
    CapabilityControl ctl = userProvider.get().getCapabilities();
    if (ctl.canAdministrateServer()) {
      return;
    }

    PluginConfig cfg = cfgFactory.getFromGerritConfig(pluginName);
    Set<String> allJails =
        new HashSet<>(Arrays.asList(cfg.getStringList(KEY_JAIL)));
    Set<String> allProtectorates =
        new HashSet<>(Arrays.asList(cfg.getStringList(KEY_PROTECTORATE)));
    Set<String> myJails = new HashSet<>();
    Set<String> myProtectorates = new HashSet<>();

    for (ProjectState p : rsrc.getControl().getProjectState().parents()) {
      String name = p.getProject().getName();
      if (allJails.contains(name)) {
        myJails.add(name);
      }
      if (allProtectorates.contains(name)) {
        myProtectorates.add(name);
      }
    }

    for (ProjectState p : newParent.tree()) {
      String name = p.getProject().getName();
      if (allProtectorates.contains(name) && !myProtectorates.contains(name)) {
        throw new ResourceConflictException(
            "not allowed to reparent under project " + name);
      }
      myJails.remove(name);
    }
    if (!myJails.isEmpty()) {
      throw new ResourceConflictException(
          "not allowed to move away from project " + myJails.iterator().next());
    }
  }

  private ProjectState getNewParentProject(Input input)
      throws UnprocessableEntityException {
    if (input != null) {
      String newParent = Strings.emptyToNull(input.parent);
      if (newParent != null) {
        ProjectState parent = projectCache.get(new Project.NameKey(newParent));
        if (parent == null) {
          throw new UnprocessableEntityException("parent project " + newParent
              + " not found");
        }
        return parent;
      }
    }
    return projectCache.getAllProjects();
  }

  public void assertReparentPermission(ProjectResource rsrc)
      throws AuthException {
    if (!canReparent(rsrc)) {
      throw new AuthException("not allowed to delete project");
    }
  }

  private boolean canReparent(ProjectResource rsrc) {
    CapabilityControl ctl = userProvider.get().getCapabilities();
    return ctl.canAdministrateServer()
        || ctl.canPerform(pluginName + "-" + REPARENT_PROJECT)
        || (ctl.canPerform(pluginName + "-" + REPARENT_OWN_PROJECT)
            && rsrc.getControl().isOwner());
  }

  @Override
  public UiAction.Description getDescription(ProjectResource rsrc) {
    return new UiAction.Description()
        .setLabel("Reparent...")
        .setTitle(isAllProjects(rsrc)
            ? String.format("No reparent of %s project",
                allProjectsName)
            : String.format("Reparent project %s", rsrc.getName()))
        .setEnabled(!isAllProjects(rsrc))
        .setVisible(canReparent(rsrc));
  }

  private boolean isAllProjects(ProjectResource rsrc) {
    return (rsrc.getControl().getProject()
        .getNameKey().equals(allProjectsName));
  }
}
