// Copyright (C) 2010 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 static java.nio.charset.StandardCharsets.UTF_8;

import com.google.common.collect.Lists;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.extensions.annotations.RequiresCapability;
import com.google.gerrit.extensions.api.accounts.AccountInput;
import com.google.gerrit.extensions.restapi.IdString;
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.server.permissions.PermissionBackendException;
import com.google.gerrit.server.restapi.account.CreateAccount;
import com.google.gerrit.sshd.CommandMetaData;
import com.google.gerrit.sshd.SshCommand;
import com.google.inject.Inject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option;

/** Create a new user account. * */
@RequiresCapability(GlobalCapability.CREATE_ACCOUNT)
@CommandMetaData(name = "create-account", description = "Create a new batch/role account")
final class CreateAccountCommand extends SshCommand {
  @Option(
      name = "--group",
      aliases = {"-g"},
      metaVar = "GROUP",
      usage = "groups to add account to")
  private List<AccountGroup.Id> groups = new ArrayList<>();

  @Option(name = "--full-name", metaVar = "NAME", usage = "display name of the account")
  private String fullName;

  @Option(name = "--email", metaVar = "EMAIL", usage = "email address of the account")
  private String email;

  @Option(name = "--ssh-key", metaVar = "-|KEY", usage = "public key for SSH authentication")
  private String sshKey;

  @Option(
      name = "--http-password",
      metaVar = "PASSWORD",
      usage = "password for HTTP authentication")
  private String httpPassword;

  @Argument(index = 0, required = true, metaVar = "USERNAME", usage = "name of the user account")
  private String username;

  @Inject private CreateAccount createAccount;

  @Override
  protected void run()
      throws IOException, ConfigInvalidException, UnloggedFailure, PermissionBackendException {
    enableGracefulStop();
    AccountInput input = new AccountInput();
    input.username = username;
    input.email = email;
    input.name = fullName;
    input.sshKey = readSshKey();
    input.httpPassword = httpPassword;
    input.groups = Lists.transform(groups, AccountGroup.Id::toString);
    try {
      createAccount.apply(TopLevelResource.INSTANCE, IdString.fromDecoded(username), input);
    } catch (RestApiException e) {
      throw die(e.getMessage());
    }
  }

  private String readSshKey() throws IOException {
    if (sshKey == null) {
      return null;
    }
    if ("-".equals(sshKey)) {
      sshKey = "";
      BufferedReader br = new BufferedReader(new InputStreamReader(in, UTF_8));
      String line;
      while ((line = br.readLine()) != null) {
        sshKey += line + "\n";
      }
    }
    return sshKey;
  }
}
