// 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.rules.cpp;

import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows;

import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import java.io.IOException;
import net.starlark.java.eval.NoneType;
import net.starlark.java.eval.Sequence;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for C++ fragments in Starlark. */
@RunWith(JUnit4.class)
public final class CppConfigurationStarlarkTest extends BuildViewTestCase {

  @Test
  public void testMinimumOsVersion() throws Exception {
    useConfiguration("--minimum_os_version=-wololoo");
    writeRuleReturning("ctx.fragments.cpp.minimum_os_version()");

    String result = (String) getConfiguredTarget("//foo:bar").get("result");
    assertThat(result).isEqualTo("-wololoo");
  }

  @Test
  public void testNullMinimumOsVersion() throws Exception {
    writeRuleReturning("ctx.fragments.cpp.minimum_os_version()");

    Object result = getConfiguredTarget("//foo:bar").get("result");
    assertThat(result).isInstanceOf(NoneType.class);
  }

  @Test
  public void testCopts() throws Exception {
    writeRuleReturning("ctx.fragments.cpp.copts");
    useConfiguration("--copt=-wololoo");

    @SuppressWarnings("unchecked")
    Sequence<String> result = (Sequence<String>) getConfiguredTarget("//foo:bar").get("result");
    assertThat(result).containsExactly("-wololoo");
  }

  @Test
  public void testCxxopts() throws Exception {
    writeRuleReturning("ctx.fragments.cpp.cxxopts");
    useConfiguration("--cxxopt=-wololoo");

    @SuppressWarnings("unchecked")
    Sequence<String> result = (Sequence<String>) getConfiguredTarget("//foo:bar").get("result");
    assertThat(result).containsExactly("-wololoo");
  }

  @Test
  public void testConlyopts() throws Exception {
    writeRuleReturning("ctx.fragments.cpp.conlyopts");
    useConfiguration("--conlyopt=-wololoo");

    @SuppressWarnings("unchecked")
    Sequence<String> result = (Sequence<String>) getConfiguredTarget("//foo:bar").get("result");
    assertThat(result).containsExactly("-wololoo");
  }

  @Test
  public void testObjcopts() throws Exception {
    writeRuleReturning("ctx.fragments.cpp.objccopts");
    useConfiguration("--objccopt=-wololoo");

    @SuppressWarnings("unchecked")
    Sequence<String> result = (Sequence<String>) getConfiguredTarget("//foo:bar").get("result");
    assertThat(result).containsExactly("-wololoo");
  }

  @Test
  public void testLinkopts() throws Exception {
    writeRuleReturning("ctx.fragments.cpp.linkopts");
    useConfiguration("--linkopt=-wololoo");

    @SuppressWarnings("unchecked")
    Sequence<String> result = (Sequence<String>) getConfiguredTarget("//foo:bar").get("result");
    assertThat(result).containsExactly("-wololoo");
  }

  @Test
  public void testExpandedApiBlocked() throws Exception {
    writeRuleReturning("foo", "pic.bzl", "pic", "ctx.fragments.cpp.force_pic()");
    writeRuleReturning("foo", "lcov.bzl", "lcov", "ctx.fragments.cpp.generate_llvm_lcov()");
    writeRuleReturning("foo", "fdo.bzl", "fdo", "ctx.fragments.cpp.fdo_instrument()");
    writeRuleReturning(
        "foo", "hdr_deps.bzl", "hdr_deps", "ctx.fragments.cpp.process_headers_in_dependencies()");
    writeRuleReturning("foo", "save.bzl", "save", "ctx.fragments.cpp.save_feature_state()");
    writeRuleReturning(
        "foo",
        "fission.bzl",
        "fission",
        "ctx.fragments.cpp.fission_active_for_current_compilation_mode()");
    AssertionError e;
    e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:pic"));
    assertThat(e).hasMessageThat().contains("Rule in 'foo' cannot use 'force_pic'");
    e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:lcov"));
    assertThat(e).hasMessageThat().contains("Rule in 'foo' cannot use 'generate_llvm_lcov'");
    e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:fdo"));
    assertThat(e).hasMessageThat().contains("Rule in 'foo' cannot use 'fdo_instrument'");
    e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:hdr_deps"));
    assertThat(e).hasMessageThat().contains("Rule in 'foo' cannot use private API");
    e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:save"));
    assertThat(e).hasMessageThat().contains("Rule in 'foo' cannot use private API");
    e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:fission"));
    assertThat(e)
        .hasMessageThat()
        .contains("Rule in 'foo' cannot use 'fission_active_for_current_compilation_mode'");
  }

  private void writeRuleReturning(String returns) throws IOException {
    writeRuleReturning("foo", "lib.bzl", "bar", returns);
  }

  private void writeRuleReturning(String path, String lib, String target, String returns)
      throws IOException {
    scratch.file(
        path + "/" + lib,
        "def _impl(ctx):",
        "  return struct(",
        "    result = " + returns,
        "  )",
        "foo = rule(implementation=_impl, fragments = ['cpp'])");
    scratch.appendFile(
        path + "/BUILD", "load(':" + lib + "', 'foo')", "foo(name='" + target + "')");
  }
}
