// Copyright (C) 2012 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.sshd.commands;

import com.google.gerrit.extensions.client.InheritableBoolean;
import com.google.gerrit.extensions.client.ProjectState;
import com.google.gerrit.extensions.client.SubmitType;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.git.MetaDataUpdate;
import com.google.gerrit.server.git.ProjectConfig;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectControl;
import com.google.gerrit.sshd.CommandMetaData;
import com.google.gerrit.sshd.SshCommand;
import com.google.inject.Inject;
import java.io.IOException;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@CommandMetaData(name = "set-project", description = "Change a project's settings")
final class SetProjectCommand extends SshCommand {
  private static final Logger log = LoggerFactory.getLogger(SetProjectCommand.class);

  @Argument(index = 0, required = true, metaVar = "NAME", usage = "name of the project")
  private ProjectControl projectControl;

  @Option(
      name = "--description",
      aliases = {"-d"},
      metaVar = "DESCRIPTION",
      usage = "description of project")
  private String projectDescription;

  @Option(
      name = "--submit-type",
      aliases = {"-t"},
      usage = "project submit type\n(default: MERGE_IF_NECESSARY)")
  private SubmitType submitType;

  @Option(name = "--contributor-agreements", usage = "if contributor agreement is required")
  private InheritableBoolean contributorAgreements;

  @Option(name = "--signed-off-by", usage = "if signed-off-by is required")
  private InheritableBoolean signedOffBy;

  @Option(name = "--content-merge", usage = "allow automatic conflict resolving within files")
  private InheritableBoolean contentMerge;

  @Option(name = "--change-id", usage = "if change-id is required")
  private InheritableBoolean requireChangeID;

  @Option(
      name = "--use-contributor-agreements",
      aliases = {"--ca"},
      usage = "if contributor agreement is required")
  void setUseContributorArgreements(@SuppressWarnings("unused") boolean on) {
    contributorAgreements = InheritableBoolean.TRUE;
  }

  @Option(
      name = "--no-contributor-agreements",
      aliases = {"--nca"},
      usage = "if contributor agreement is not required")
  void setNoContributorArgreements(@SuppressWarnings("unused") boolean on) {
    contributorAgreements = InheritableBoolean.FALSE;
  }

  @Option(
      name = "--use-signed-off-by",
      aliases = {"--so"},
      usage = "if signed-off-by is required")
  void setUseSignedOffBy(@SuppressWarnings("unused") boolean on) {
    signedOffBy = InheritableBoolean.TRUE;
  }

  @Option(
      name = "--no-signed-off-by",
      aliases = {"--nso"},
      usage = "if signed-off-by is not required")
  void setNoSignedOffBy(@SuppressWarnings("unused") boolean on) {
    signedOffBy = InheritableBoolean.FALSE;
  }

  @Option(name = "--use-content-merge", usage = "allow automatic conflict resolving within files")
  void setUseContentMerge(@SuppressWarnings("unused") boolean on) {
    contentMerge = InheritableBoolean.TRUE;
  }

  @Option(
      name = "--no-content-merge",
      usage = "don't allow automatic conflict resolving within files")
  void setNoContentMerge(@SuppressWarnings("unused") boolean on) {
    contentMerge = InheritableBoolean.FALSE;
  }

  @Option(
      name = "--require-change-id",
      aliases = {"--id"},
      usage = "if change-id is required")
  void setRequireChangeId(@SuppressWarnings("unused") boolean on) {
    requireChangeID = InheritableBoolean.TRUE;
  }

  @Option(
      name = "--no-change-id",
      aliases = {"--nid"},
      usage = "if change-id is not required")
  void setNoChangeId(@SuppressWarnings("unused") boolean on) {
    requireChangeID = InheritableBoolean.FALSE;
  }

  @Option(
      name = "--project-state",
      aliases = {"--ps"},
      usage = "project's visibility state")
  private ProjectState state;

  @Option(name = "--max-object-size-limit", usage = "max Git object size for this project")
  private String maxObjectSizeLimit;

  @Inject private MetaDataUpdate.User metaDataUpdateFactory;

  @Inject private ProjectCache projectCache;

  @Override
  protected void run() throws Failure {
    if (!projectControl.isOwner()) {
      throw new UnloggedFailure(1, "restricted to project owner");
    }
    Project ctlProject = projectControl.getProject();
    Project.NameKey nameKey = ctlProject.getNameKey();
    String name = ctlProject.getName();
    final StringBuilder err = new StringBuilder();

    try (MetaDataUpdate md = metaDataUpdateFactory.create(nameKey)) {
      ProjectConfig config = ProjectConfig.read(md);
      Project project = config.getProject();

      if (requireChangeID != null) {
        project.setRequireChangeID(requireChangeID);
      }
      if (submitType != null) {
        project.setSubmitType(submitType);
      }
      if (contentMerge != null) {
        project.setUseContentMerge(contentMerge);
      }
      if (contributorAgreements != null) {
        project.setUseContributorAgreements(contributorAgreements);
      }
      if (signedOffBy != null) {
        project.setUseSignedOffBy(signedOffBy);
      }
      if (projectDescription != null) {
        project.setDescription(projectDescription);
      }
      if (state != null) {
        project.setState(state);
      }
      if (maxObjectSizeLimit != null) {
        project.setMaxObjectSizeLimit(maxObjectSizeLimit);
      }
      md.setMessage("Project settings updated");
      config.commit(md);
    } catch (RepositoryNotFoundException notFound) {
      err.append("Project ").append(name).append(" not found\n");
    } catch (IOException | ConfigInvalidException e) {
      final String msg = "Cannot update project " + name;
      log.error(msg, e);
      err.append("error: ").append(msg).append("\n");
    }
    projectCache.evict(ctlProject);

    if (err.length() > 0) {
      while (err.charAt(err.length() - 1) == '\n') {
        err.setLength(err.length() - 1);
      }
      throw die(err.toString());
    }
  }
}
