// 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.base.Strings;
import com.google.common.collect.Lists;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.entities.AccountGroup;
import com.google.gerrit.extensions.annotations.RequiresCapability;
import com.google.gerrit.extensions.api.accounts.AccountInput;
import com.google.gerrit.extensions.auth.AuthTokenInput;
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.server.account.InvalidAuthTokenException;
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;

  @Option(name = "--token", metaVar = "TOKEN", usage = "token for HTTP authentication")
  private String token;

  @Option(
      name = "--token-id",
      depends = {"--token"},
      metaVar = "TOKEN",
      usage = "ID for the authentication token")
  private String tokenId;

  @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;

    if (!Strings.isNullOrEmpty(token)) {
      AuthTokenInput tokenInput = new AuthTokenInput();
      if (!Strings.isNullOrEmpty(tokenId)) {
        tokenInput.id = tokenId;
      }
      tokenInput.token = token;

      input.tokens = List.of(tokenInput);
    } else {
      input.tokens = List.of();
    }

    input.groups = Lists.transform(groups, AccountGroup.Id::toString);
    try {
      @SuppressWarnings("unused")
      var unused =
          createAccount.apply(TopLevelResource.INSTANCE, IdString.fromDecoded(username), input);
    } catch (RestApiException | InvalidAuthTokenException e) {
      throw die(e.getMessage());
    }
  }

  @Nullable
  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;
  }
}
