// Copyright 2017 The Bazel Authors. All rights reserved.
//
// 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.devtools.build.lib.runtime;

import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.verify;

import com.google.common.collect.ImmutableList;
import com.google.common.eventbus.EventBus;
import com.google.devtools.build.lib.analysis.BlazeDirectories;
import com.google.devtools.build.lib.analysis.ServerDirectories;
import com.google.devtools.build.lib.exec.BinTools;
import com.google.devtools.build.lib.runtime.commands.VersionCommand;
import com.google.devtools.build.lib.server.FailureDetails.Crash;
import com.google.devtools.build.lib.server.FailureDetails.Crash.Code;
import com.google.devtools.build.lib.server.FailureDetails.FailureDetail;
import com.google.devtools.build.lib.util.DetailedExitCode;
import com.google.devtools.build.lib.vfs.DigestHashFunction;
import com.google.devtools.build.lib.vfs.FileSystem;
import com.google.devtools.build.lib.vfs.inmemoryfs.InMemoryFileSystem;
import com.google.devtools.common.options.OptionsBase;
import com.google.devtools.common.options.OptionsParser;
import com.google.devtools.common.options.OptionsParsingResult;
import com.google.protobuf.Any;
import com.google.protobuf.ByteString;
import com.google.protobuf.BytesValue;
import com.google.protobuf.StringValue;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicReference;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.Mockito;

/** Tests for {@link BlazeRuntime} static methods. */
@RunWith(JUnit4.class)
public class BlazeRuntimeTest {

  @Test
  public void optionSplitting() {
    BlazeRuntime.CommandLineOptions options =
        BlazeRuntime.splitStartupOptions(
            ImmutableList.of(),
            "--install_base=/foo --host_jvm_args=-Xmx1B",
            "build",
            "//foo:bar",
            "--nobuild");
    assertThat(options.getStartupArgs())
        .isEqualTo(Arrays.asList("--install_base=/foo --host_jvm_args=-Xmx1B"));
    assertThat(options.getOtherArgs()).isEqualTo(Arrays.asList("build", "//foo:bar", "--nobuild"));
  }

  // A regression test to make sure that the 'no' prefix is handled correctly.
  @Test
  public void optionSplittingNoPrefix() {
    BlazeRuntime.CommandLineOptions options =
        BlazeRuntime.splitStartupOptions(ImmutableList.of(), "--nobatch", "build");
    assertThat(options.getStartupArgs()).isEqualTo(Arrays.asList("--nobatch"));
    assertThat(options.getOtherArgs()).isEqualTo(Arrays.asList("build"));
  }

  private static final ImmutableList<Class<? extends OptionsBase>> COMMAND_ENV_REQUIRED_OPTIONS =
      ImmutableList.of(CommonCommandOptions.class, ClientOptions.class);

  @Test
  public void crashTest() throws Exception {
    FileSystem fs = new InMemoryFileSystem(DigestHashFunction.SHA256);
    ServerDirectories serverDirectories =
        new ServerDirectories(
            fs.getPath("/install"), fs.getPath("/output"), fs.getPath("/output_user"));
    BlazeRuntime runtime =
        new BlazeRuntime.Builder()
            .setFileSystem(fs)
            .setProductName("foo product")
            .setServerDirectories(serverDirectories)
            .setStartupOptionsProvider(Mockito.mock(OptionsParsingResult.class))
            .build();
    AtomicReference<String> shutdownMessage = new AtomicReference<>();
    BlazeDirectories directories =
        new BlazeDirectories(
            serverDirectories, fs.getPath("/workspace"), fs.getPath("/system_javabase"), "blaze");
    BlazeWorkspace workspace = runtime.initWorkspace(directories, BinTools.empty(directories));
    EventBus eventBus = Mockito.mock(EventBus.class);
    OptionsParser options =
        OptionsParser.builder().optionsClasses(COMMAND_ENV_REQUIRED_OPTIONS).build();
    Thread commandThread = Mockito.mock(Thread.class);
    CommandEnvironment env =
        new CommandEnvironment(
            runtime,
            workspace,
            eventBus,
            commandThread,
            VersionCommand.class.getAnnotation(Command.class),
            options,
            ImmutableList.of(),
            0L,
            0L,
            ImmutableList.of(),
            shutdownMessage::set);
    runtime.beforeCommand(env, options.getOptions(CommonCommandOptions.class));
    DetailedExitCode oom =
        DetailedExitCode.of(
            FailureDetail.newBuilder()
                .setCrash(Crash.newBuilder().setCode(Code.CRASH_OOM))
                .build());
    runtime.cleanUpForCrash(oom);
    BlazeCommandResult mainThreadCrash =
        BlazeCommandResult.failureDetail(
            FailureDetail.newBuilder()
                .setCrash(Crash.newBuilder().setCode(Code.CRASH_UNKNOWN))
                .build());
    assertThat(runtime.afterCommand(env, mainThreadCrash).getDetailedExitCode()).isEqualTo(oom);
    // Confirm that runtime interrupted the command thread.
    verify(commandThread).interrupt();
    assertThat(shutdownMessage.get()).isEqualTo("foo product is crashing: ");
  }

  @Test
  public void resultExtensions() throws Exception {
    FileSystem fs = new InMemoryFileSystem(DigestHashFunction.SHA256);
    ServerDirectories serverDirectories =
        new ServerDirectories(
            fs.getPath("/install"), fs.getPath("/output"), fs.getPath("/output_user"));
    BlazeRuntime runtime =
        new BlazeRuntime.Builder()
            .setFileSystem(fs)
            .setProductName("bazel")
            .setServerDirectories(serverDirectories)
            .setStartupOptionsProvider(Mockito.mock(OptionsParsingResult.class))
            .build();
    BlazeDirectories directories =
        new BlazeDirectories(
            serverDirectories, fs.getPath("/workspace"), fs.getPath("/system_javabase"), "blaze");
    BlazeWorkspace workspace = runtime.initWorkspace(directories, BinTools.empty(directories));
    CommandEnvironment env =
        new CommandEnvironment(
            runtime,
            workspace,
            Mockito.mock(EventBus.class),
            Thread.currentThread(),
            VersionCommand.class.getAnnotation(Command.class),
            OptionsParser.builder().optionsClasses(COMMAND_ENV_REQUIRED_OPTIONS).build(),
            ImmutableList.of(),
            0L,
            0L,
            ImmutableList.of(),
            s -> {});
    Any anyFoo = Any.pack(StringValue.of("foo"));
    Any anyBar = Any.pack(BytesValue.of(ByteString.copyFromUtf8("bar")));
    env.addResponseExtensions(ImmutableList.of(anyFoo, anyBar));
    assertThat(runtime.afterCommand(env, BlazeCommandResult.success()).getResponseExtensions())
        .containsExactly(anyFoo, anyBar);
  }

  @Test
  public void addsCommandsFromModules() throws Exception {
    FileSystem fs = new InMemoryFileSystem(DigestHashFunction.SHA256);
    ServerDirectories serverDirectories =
        new ServerDirectories(
            fs.getPath("/install"), fs.getPath("/output"), fs.getPath("/output_user"));
    BlazeRuntime runtime =
        new BlazeRuntime.Builder()
            .addBlazeModule(new FooCommandModule())
            .addBlazeModule(new BarCommandModule())
            .setFileSystem(fs)
            .setProductName("bazel")
            .setServerDirectories(serverDirectories)
            .setStartupOptionsProvider(Mockito.mock(OptionsParsingResult.class))
            .build();

    assertThat(runtime.getCommandMap().keySet()).containsExactly("foo", "bar").inOrder();
    assertThat(runtime.getCommandMap().get("foo")).isInstanceOf(FooCommandModule.FooCommand.class);
    assertThat(runtime.getCommandMap().get("bar")).isInstanceOf(BarCommandModule.BarCommand.class);
  }

  private static class FooCommandModule extends BlazeModule {
    @Command(name = "foo", shortDescription = "", help = "")
    private static class FooCommand implements BlazeCommand {

      @Override
      public BlazeCommandResult exec(CommandEnvironment env, OptionsParsingResult options) {
        return null;
      }
    }

    @Override
    public void serverInit(OptionsParsingResult startupOptions, ServerBuilder builder) {
      builder.addCommands(new FooCommand());
    }
  }

  private static class BarCommandModule extends BlazeModule {
    @Command(name = "bar", shortDescription = "", help = "")
    private static class BarCommand implements BlazeCommand {

      @Override
      public BlazeCommandResult exec(CommandEnvironment env, OptionsParsingResult options) {
        return null;
      }
    }

    @Override
    public void serverInit(OptionsParsingResult startupOptions, ServerBuilder builder) {
      builder.addCommands(new BarCommand());
    }
  }
}
