// Copyright (C) 2020 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.truth.Truth.assertThat;
import static com.google.common.truth.TruthJUnit.assume;

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 com.google.gerrit.testing.ConfigSuite;
import com.google.inject.Module;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.eclipse.jgit.lib.Config;
import org.junit.Test;
import org.junit.runner.RunWith;

@NoHttpd
@UseSsh
@Sandboxed
@RunWith(ConfigSuite.class)
public class SshDaemonIT extends AbstractDaemonTest {
  @ConfigSuite.Parameter protected Config config;

  @ConfigSuite.Config
  public static Config gracefulConfig() {
    Config config = new Config();
    config.setString("sshd", null, "gracefulStopTimeout", "10s");
    return config;
  }

  @Override
  public Module createSshModule() {
    return new TestSshCommandModule();
  }

  @Test
  public void nonGracefulCommandIsStoppedImmediately() throws Exception {
    Future<Integer> future = startCommand(false);
    restart();
    assertThat(future.get()).isEqualTo(-1);
  }

  @Test
  public void gracefulCommandIsStoppedGracefully() throws Exception {
    assume().that(isGracefulStopEnabled()).isTrue();

    Future<Integer> future = startCommand(true);
    restart();
    assertThat(future.get()).isEqualTo(0);
  }

  private Future<Integer> startCommand(boolean graceful) throws Exception {
    Future<Integer> future =
        Executors.newFixedThreadPool(1)
            .submit(
                () ->
                    userSshSession.execAndReturnStatus(
                        String.format("%sgraceful -d 5", graceful ? "" : "non-")));
    TestCommand.syncPoint.await();
    return future;
  }

  private boolean isGracefulStopEnabled() {
    return cfg.getTimeUnit("sshd", null, "gracefulStopTimeout", 0, TimeUnit.SECONDS) > 0;
  }
}
