// Copyright (C) 2016 Ericsson
//
// 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 com.google.common.base.Charsets;
import com.google.common.hash.Hashing;
import com.google.gerrit.extensions.annotations.PluginCanonicalWebUrl;
import com.google.gerrit.extensions.api.groups.GroupInput;
import com.google.gerrit.extensions.common.GroupInfo;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.extensions.restapi.TopLevelResource;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.config.AllProjectsNameProvider;
import com.google.gerrit.server.group.CreateGroup;
import com.google.gerrit.server.project.CreateProjectArgs;
import com.google.gerrit.server.project.ProjectControl;
import com.google.gerrit.server.validators.ProjectCreationValidationListener;
import com.google.gerrit.server.validators.ValidationException;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Singleton;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;

@Singleton
public class ProjectCreationValidator
    implements ProjectCreationValidationListener {
  private static final Logger log =
      LoggerFactory.getLogger(ProjectCreationValidator.class);

  private static final String AN_ERROR_OCCURRED_MSG =
      "An error occurred while creating project, please contact Gerrit support";

  private static final String SEE_DOCUMENTATION_MSG =
      "\n\nSee documentation for more info: %s";

  private static final String MUST_BE_OWNER_TO_CREATE_PROJECT_MSG =
      "You must be owner of the parent project \"%s\" to create a nested project."
          + SEE_DOCUMENTATION_MSG;

  private static final String ROOT_PROJECT_CANNOT_CONTAINS_SLASHES_MSG =
      "Root project name cannot contains slashes." + SEE_DOCUMENTATION_MSG;

  private static final String REGULAR_PROJECT_NOT_ALLOWED_AS_ROOT_MSG =
      "Regular projects are not allowed as root.\n\n"
          + "Please create a root parent project (project with option "
          + "\"Only serve as parent for other projects\") that will hold "
          + "all your access rights and then create your regular project that "
          + "inherits rights from your root project.\n\n" + "Example:\n"
          + "\"someOrganization\"->parent project\n"
          + "\"someOrganization/someProject\"->regular project."
          + SEE_DOCUMENTATION_MSG;

  private static final String PROJECT_MUST_START_WITH_PARENT_NAME_MSG =
      "Project name must start with parent project name, e.g. %s."
          + SEE_DOCUMENTATION_MSG;

  private final CreateGroup.Factory createGroupFactory;
  private final String documentationUrl;
  private final AllProjectsNameProvider allProjectsName;

  @Inject
  public ProjectCreationValidator(CreateGroup.Factory createGroupFactory,
      @PluginCanonicalWebUrl String url,
      AllProjectsNameProvider allProjectsName) {
    this.createGroupFactory = createGroupFactory;
    this.documentationUrl = url + "Documentation/index.html";
    this.allProjectsName = allProjectsName;

  }

  @Override
  public void validateNewProject(CreateProjectArgs args)
      throws ValidationException {
    String name = args.getProjectName();
    log.debug("validating creation of {}", name);
    ProjectControl parentCtrl = args.newParent;
    if (parentCtrl.getUser().getCapabilities().canAdministrateServer()) {
      // Admins can bypass any rules to support creating projects that doesn't
      // comply with the new naming rules. New projects structures have to
      // comply but we need to be able to add new project to an existing non
      // compliant structure.
      log.debug("admin is creating project, bypassing all rules");
      return;
    }

    if (allProjectsName.get().equals(parentCtrl.getProject().getNameKey())) {
      validateRootProject(name, args.permissionsOnly);
      args.ownerIds.add(createGroup(name + "-admins"));
      return;
    }

    validateProject(name, parentCtrl);
  }

  private AccountGroup.UUID createGroup(String name)
      throws ValidationException {
    try {
      GroupInfo groupInfo = null;
      try {
        groupInfo = createGroupFactory.create(name)
            .apply(TopLevelResource.INSTANCE, new GroupInput());
      } catch (ResourceConflictException e) {
        // name already exists, make sure it is unique by adding a abbreviated
        // sha1
        String nameWithSha1 = name + "-" + Hashing.sha1()
            .hashString(name, Charsets.UTF_8).toString().substring(0, 7);
        log.info(
            "Failed to create group name {} because of a conflict: {}, trying to create {} instead",
            name, e.getMessage(), nameWithSha1);
        groupInfo = createGroupFactory.create(nameWithSha1)
            .apply(TopLevelResource.INSTANCE, new GroupInput());
      }
      return AccountGroup.UUID.parse(groupInfo.id);
    } catch (RestApiException | OrmException | IOException e ) {
      log.error("Failed to create project " + name + ": " + e.getMessage(), e);
      throw new ValidationException(AN_ERROR_OCCURRED_MSG);
    }
  }

  private void validateRootProject(String name, boolean permissionOnly)
      throws ValidationException {
    log.debug("validating root project name {}", name);
    if (name.contains("/")) {
      log.debug("rejecting creation of {}: name contains slashes", name);
      throw new ValidationException(String
          .format(ROOT_PROJECT_CANNOT_CONTAINS_SLASHES_MSG, documentationUrl));
    }
    if (!permissionOnly) {
      log.debug("rejecting creation of {}: missing permissions only option",
          name);
      throw new ValidationException(String
          .format(REGULAR_PROJECT_NOT_ALLOWED_AS_ROOT_MSG, documentationUrl));
    }
    log.debug("allowing creation of root project {}", name);
  }

  private void validateProject(String name, ProjectControl parentCtrl)
      throws ValidationException {
    log.debug("validating name prefix of {}", name);
    Project parent = parentCtrl.getProject();
    String prefix = parent.getName() + "/";
    if (!name.startsWith(prefix)) {
      log.debug("rejecting creation of {}: name is not starting with {}", name,
          prefix);
      throw new ValidationException(
          String.format(PROJECT_MUST_START_WITH_PARENT_NAME_MSG, prefix + name,
              documentationUrl));
    }
    if (!parentCtrl.isOwner()) {
      log.debug("rejecting creation of {}: user is not owner of {}", name,
          parent.getName());
      throw new ValidationException(
          String.format(MUST_BE_OWNER_TO_CREATE_PROJECT_MSG, parent.getName(),
              documentationUrl));
    }
    log.debug("allowing creation of project {}", name);
  }
}
