// Copyright (C) 2017 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.acceptance.ssh;

import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;

import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Streams;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.acceptance.Sandboxed;
import com.google.gerrit.acceptance.UseSsh;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Spliterator;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import org.junit.Test;

@NoHttpd
@UseSsh
public class SshCommandsIT extends AbstractDaemonTest {
  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  // TODO: It would be better to dynamically generate these lists
  private static final ImmutableList<String> COMMON_ROOT_COMMANDS =
      ImmutableList.of(
          "apropos",
          "check-project-access",
          "close-connection",
          "convert-ref-storage",
          "flush-caches",
          "gc",
          "logging",
          "ls-groups",
          "ls-members",
          "ls-projects",
          "ls-user-refs",
          "plugin",
          "reload-config",
          "show-caches",
          "show-connections",
          "show-queue",
          "version");

  private static final ImmutableList<String> MASTER_ONLY_ROOT_COMMANDS =
      ImmutableList.of(
          "ban-commit",
          "create-account",
          "create-branch",
          "create-group",
          "create-project",
          "index",
          "query",
          "receive-pack",
          "rename-group",
          "review",
          "sequence",
          "set-account",
          "set-head",
          "set-members",
          "set-project",
          "set-project-parent",
          "set-reviewers",
          "set-topic",
          "stream-events",
          "test-submit",
          "migrate-externalids-to-insensitive");

  private static final ImmutableList<String> EMPTY = ImmutableList.of();
  private static final ImmutableMap<String, List<String>> MASTER_COMMANDS =
      ImmutableMap.<String, List<String>>builder()
          .put("kill", EMPTY)
          .put("ps", EMPTY)
          // TODO(dpursehouse): Add "scp" and "suexec"
          .put(
              "gerrit",
              Streams.concat(COMMON_ROOT_COMMANDS.stream(), MASTER_ONLY_ROOT_COMMANDS.stream())
                  .sorted()
                  .collect(toImmutableList()))
          .put(
              "gerrit index",
              ImmutableList.of(
                  "changes", "changes-in-project")) // "activate" and "start" are not included
          .put("gerrit logging", ImmutableList.of("ls", "set"))
          .put(
              "gerrit plugin",
              ImmutableList.of("add", "enable", "install", "ls", "reload", "remove", "rm"))
          .put("gerrit test-submit", ImmutableList.of("rule", "type"))
          .put("gerrit sequence", ImmutableList.of("set", "show"))
          .build();

  private static final ImmutableMap<String, List<String>> SLAVE_COMMANDS =
      ImmutableMap.of(
          "kill",
          EMPTY,
          "gerrit",
          COMMON_ROOT_COMMANDS,
          "gerrit plugin",
          ImmutableList.of("add", "enable", "install", "ls", "reload", "remove", "rm"));

  @Test
  @Sandboxed
  public void sshCommandCanBeExecuted() throws Exception {
    testCommandExecution(MASTER_COMMANDS);

    restartAsSlave();
    testCommandExecution(SLAVE_COMMANDS);
  }

  private void testCommandExecution(Map<String, List<String>> commands) throws Exception {
    for (String root : commands.keySet()) {
      List<String> cmds = commands.get(root);
      if (cmds.isEmpty()) {
        testCommandExecution(root);
      } else {
        for (String cmd : cmds) {
          testCommandExecution(String.format("%s %s", root, cmd));
        }
      }
    }
  }

  private void testCommandExecution(String cmd) throws Exception {
    // We can't assert that adminSshSession.hasError() is false, because using the --help
    // option causes the usage info to be written to stderr. Instead, we assert on the
    // content of the stderr, which will always start with "gerrit command" when the --help
    // option is used.
    logger.atFine().log("%s", cmd);
    adminSshSession.exec(String.format("%s --help", cmd));
    String response = adminSshSession.getError();
    assertWithMessage(String.format("command %s failed: %s", cmd, response))
        .that(response)
        .startsWith(cmd);
  }

  @Test
  public void nonExistingCommandFails() throws Exception {
    adminSshSession.exec("gerrit non-existing-command --help");
    assertThat(adminSshSession.getError())
        .startsWith("fatal: gerrit: non-existing-command: not found");
  }

  @Test
  @Sandboxed
  public void listCommands() throws Exception {
    adminSshSession.exec("gerrit --help");
    List<String> commands = parseCommandsFromGerritHelpText(adminSshSession.getError());
    assertThat(commands).containsExactlyElementsIn(MASTER_COMMANDS.get("gerrit")).inOrder();

    restartAsSlave();
    adminSshSession.exec("gerrit --help");
    commands = parseCommandsFromGerritHelpText(adminSshSession.getError());
    assertThat(commands).containsExactlyElementsIn(SLAVE_COMMANDS.get("gerrit")).inOrder();
  }

  @Test
  @Sandboxed
  public void showConnections() throws Exception {
    Spliterator<String> connectionsOutput =
        getOutputLines(adminSshSession.exec("gerrit show-connections"));

    assertThat(findConnectionsInOutput(connectionsOutput, "user")).hasSize(1);
  }

  @Test
  @Sandboxed
  public void cloeConnections() throws Exception {
    List<String> connectionsOutput =
        findConnectionsInOutput(
            getOutputLines(adminSshSession.exec("gerrit show-connections")), "user");
    String connectionId =
        Splitter.on(" ")
            .trimResults()
            .omitEmptyStrings()
            .split(connectionsOutput.get(0))
            .iterator()
            .next();

    String closeConnectionOutput = adminSshSession.exec("gerrit close-connection " + connectionId);
    assertThat(closeConnectionOutput).contains(connectionId);

    assertThat(
            findConnectionsInOutput(
                getOutputLines(adminSshSession.exec("gerrit show-connections")), "user"))
        .isEmpty();
  }

  private List<String> parseCommandsFromGerritHelpText(String helpText) {
    List<String> commands = new ArrayList<>();

    List<String> lines = Splitter.on("\n").splitToList(helpText);

    // Skip all lines including the line starting with "Available commands"
    int row = 0;
    do {
      row++;
    } while (row < lines.size() && !lines.get(row - 1).startsWith("Available commands"));

    // Skip all empty lines
    while (lines.get(row).trim().isEmpty()) {
      row++;
    }

    // Parse commands from all lines that are indented (start with a space)
    while (row < lines.size() && lines.get(row).startsWith(" ")) {
      String line = lines.get(row).trim();
      // Abort on empty line
      if (line.isEmpty()) {
        break;
      }

      // Cut off command description if there is one
      int endOfCommand = line.indexOf(' ');
      commands.add(endOfCommand > 0 ? line.substring(0, line.indexOf(' ')) : line);
      row++;
    }

    return commands;
  }

  private List<String> findConnectionsInOutput(Spliterator<String> connectionsOutput, String user) {
    List<String> connections =
        StreamSupport.stream(connectionsOutput, false)
            .filter(s -> s.contains("localhost") && s.contains(user))
            .collect(Collectors.toList());
    return connections;
  }

  private Spliterator<String> getOutputLines(String output) throws Exception {
    return Splitter.on("\n").trimResults().omitEmptyStrings().split(output).spliterator();
  }
}
