// Copyright 2018 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.blackbox.junit;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.devtools.build.lib.blackbox.bazel.BlackBoxTestEnvironmentImpl;
import com.google.devtools.build.lib.blackbox.bazel.CrossToolsSetup;
import com.google.devtools.build.lib.blackbox.bazel.CxxToolsSetup;
import com.google.devtools.build.lib.blackbox.bazel.DefaultToolsSetup;
import com.google.devtools.build.lib.blackbox.bazel.JavaToolsSetup;
import com.google.devtools.build.lib.blackbox.framework.BlackBoxTestContext;
import com.google.devtools.build.lib.blackbox.framework.BlackBoxTestEnvironment;
import com.google.devtools.build.lib.blackbox.framework.PathUtils;
import com.google.devtools.build.lib.blackbox.framework.ToolsSetup;
import java.nio.file.Path;
import java.util.List;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.rules.TestName;

/**
 * Abstract base class for all JUnit integration tests for Bazel and Blaze.
 *
 * <p>Reuses {@link BlackBoxTestEnvironment} for all the test methods in the class. Initializes the
 * test environment and creates the test context for thet concrete test methods. Alternatively,
 * {@link #setUp()} method can be overridden in concrete tests, and {@link
 * #prepareEnvironment(ImmutableList)} method be called for each test method separately to let them
 * initialize the unique set of tools.
 *
 * <p>See {@link BlackBoxTestEnvironment}, {@link BlackBoxTestContext}
 */
public abstract class AbstractBlackBoxTest {
  public static final List<ToolsSetup> DEFAULT_TOOLS =
      Lists.newArrayList(
          new DefaultToolsSetup(),
          new JavaToolsSetup(),
          new CxxToolsSetup(),
          new CrossToolsSetup());

  @Rule public TestName testName = new TestName();

  /**
   * Shares the common infrastructure of a test group (execution service), serves as a test context
   * factory.
   */
  private static BlackBoxTestEnvironment testEnvironment;
  /** Test context, available to the concrete test methods through a getter {@link #context()} */
  private BlackBoxTestContext context;

  @BeforeClass
  public static void beforeClass() {
    testEnvironment = new BlackBoxTestEnvironmentImpl();
  }

  @AfterClass
  public static void afterClass() {
    testEnvironment.dispose();
  }

  @Before
  public void setUp() throws Exception {
    prepareEnvironment(getAdditionalTools());
  }

  @After
  public void tearDown() throws Exception {
    if (context != null) {
      try {
        context.bazel().shutdown();
      } finally {
        Path workDir = context.getWorkDir();
        if (workDir != null) {
          PathUtils.deleteTreeWithRetry(workDir);
        }
      }
    }
  }

  /**
   * Prepare the test environment for the test method and set the test context .
   *
   * @param tools all {@link ToolsSetup} to be called during environment initialization
   * @throws Exception if any {@link ToolsSetup} call fails
   */
  protected void prepareEnvironment(ImmutableList<ToolsSetup> tools) throws Exception {
    context = testEnvironment.prepareEnvironment(testName.getMethodName(), tools);
  }

  /**
   * Getter method for test context. Concrete test methods should only use the test context, but not
   * modify it.
   *
   * @return test context
   */
  protected BlackBoxTestContext context() {
    return context;
  }

  /**
   * Concrete test can either override this method to provide the list of additional tools besides
   * {@link #DEFAULT_TOOLS} to be initialized for all test methods, or call {@link
   * #prepareEnvironment(ImmutableList)} in each test method separately, passing the list of tools
   *
   * @return the list of {@link ToolsSetup} to be called in environment initialization
   */
  protected ImmutableList<ToolsSetup> getAdditionalTools() {
    return ImmutableList.of();
  }
}
