// Copyright 2020 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.buildtool;

import static com.google.common.truth.Truth.assertThat;

import com.google.devtools.build.lib.buildtool.util.GoogleBuildIntegrationTestCase;
import com.google.devtools.build.lib.testutil.Suite;
import com.google.devtools.build.lib.testutil.TestSpec;
import com.google.devtools.build.lib.vfs.Path;
import java.io.IOException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Test of compilation of involving change command line arguments.
 *
 */
@TestSpec(size = Suite.MEDIUM_TESTS)
@RunWith(JUnit4.class)
public class CompileAfterOptionChangeTest extends GoogleBuildIntegrationTestCase {

  private void writeSourceFiles() throws IOException {
    // A program that uses a command line argument to the compilation to
    // create its output
    write("pkg/hello.cc",
          "#include <stdio.h>",
          "#ifndef GREETING",
          "#define GREETING DEFAULT_GREETING",
          "#endif",
          "extern void printf(const char *s);",
          "int main() {",
          "  printf(\"%s\", GREETING \", World!\");",
          "}");
  }

  /**
   * Adds the specified options and builds the application.
   * Note that any options set in buildApp() are sticky for subsequent calls
   * to buildApp() from the same test method.
   */
  private BuildResult buildApp(String... requestArgs) throws Exception {
    addOptions(requestArgs);
    return buildTarget("//pkg:hello");
  }

  /**
   * Test of minor variations between actions. We pass command line options to
   * gcc and test if we correctly rebuild the application
   */
  @Test
  public void testChangingCommandLineOptionRebuilds() throws Exception {
    writeSourceFiles();
    write("pkg/BUILD",
          "cc_binary(name='hello',",
          "          malloc = '//base:system_malloc',",
          "          srcs=['hello.cc'],",
          "          defines = ['DEFAULT_GREETING=\\\\\\\"Hello\\\\\\\"'])");
    // Here's why we need so many backslashes:
    //   Java source:            "...'DEFAULT_GREETING=\\\\\\\"Hello\\\\\\\"'..."
    //   BUILD file:              ...'DEFAULT_GREETING=\\\"Hello\\\"'...
    //   Makefile:                ... -DDEFAULT_GREETING=\"Hello\" ...
    //   Arguments passed to sh:  ... -DDEFAULT_GREETING=\"Hello\" ...
    //   Arguments passed to gcc: ... -DDEFAULT_GREETING="Hello" ...
    // Blaze doesn't go through the "Makefile" or "sh" stages, but Blaze's
    // treatment of backslash escapes is compatible with make-dbg, which does.

    ////////////////////////////////////////////////////////////////////////
    // (1) Build using default request options:
    buildApp();
    Path hello = getExecutableLocation("//pkg:hello");

    // Check the output of 'hello':
    assertThat(run(hello)).isEqualTo("Hello, World!");

    ////////////////////////////////////////////////////////////////////////
    // (2) Build again using a different cc_binary rule
    write("pkg/BUILD",
          "cc_binary(name='hello',",
          "          malloc = '//base:system_malloc',",
          "          srcs=['hello.cc'],",
          "          defines = ['DEFAULT_GREETING=\\'\"Hello again\"\\''])");
    // Here's why we need so many quotes and backslashes:
    //   Java source:            "...'DEFAULT_GREETING=\\'\"Hello again\"\\''..."
    //   BUILD file:              ...'DEFAULT_GREETING=\'"Hello again"\''...
    //  (Makefile:                ... -DDEFAULT_GREETING='"Hello again"' ...)
    //  (Arguments passed to sh:  ... -DDEFAULT_GREETING='"Hello again"' ...)
    //   Arguments passed to gcc: ... -DDEFAULT_GREETING="Hello again" ...
    // Blaze doesn't go through the "Makefile" or "sh" stages, but Blaze's
    // treatment of backslash escapes is compatible with make-dbg, which does.

    buildApp();

    // Check that the output of 'hello' was affected by changing the rule
    assertThat(run(hello)).isEqualTo("Hello again, World!");

    ////////////////////////////////////////////////////////////////////////
    // (3) Build again using additional command line options:
    write("pkg/BUILD",
          "cc_binary(name='hello',",
          "          malloc = '//base:system_malloc',",
          "          srcs=['hello.cc'])");

    buildApp("--copt", "-DGREETING=\"Hi\"");

    // Check that the output of 'hello' was affected by adding the request
    // options:
    assertThat(run(hello)).isEqualTo("Hi, World!");

    ////////////////////////////////////////////////////////////////////////
    // (4) Build again using different command line options:

    // We need the -U option to override the -D option set by the
    // previous call to buildApp() earlier in this method.
    buildApp("--copt", "-UGREETING", "--copt", "-DGREETING=\"Goodbye\"");
    // Check that the output of 'hello' was affected by changing the request
    // options:
    assertThat(run(hello)).isEqualTo("Goodbye, World!");
  }

}
