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

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

import com.google.devtools.build.lib.actions.util.ActionsTestUtil;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.actions.FileWriteAction;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for {@link AndroidDeviceScriptFixture}. */
@RunWith(JUnit4.class)
public class AndroidDeviceScriptFixtureTest extends AndroidBuildViewTestCase {

  @Before
  public void setup() throws Exception {
    scratch.file("scripts/BUILD", "exports_files(['my_script.sh'])");
    scratch.file(
        "java/com/app/BUILD",
        "android_binary(",
        "  name = 'app',",
        "  manifest = 'AndroidManifest.xml',",
        ")");
    scratch.file(
        "java/com/app/support/BUILD",
        "android_binary(",
        "  name = 'support',",
        "  manifest = 'AndroidManifest.xml',",
        ")",
        "genrule(",
        "  name = 'genrule',",
        "  outs = ['generated.apk'],",
        "  cmd = 'touch $(OUTS)',",
        ")");
  }

  @Test
  public void testScriptFixture() throws Exception {
    scratch.file(
        "javatests/com/app/BUILD",
        "android_device_script_fixture(",
        "  name = 'fixture',",
        "  script = '//scripts:my_script.sh',",
        ")");
    ConfiguredTarget fixture = getConfiguredTarget("//javatests/com/app:fixture");
    assertThat(fixture).isNotNull();
    AndroidDeviceScriptFixtureInfoProvider deviceScriptFixtureInfoProvider =
        fixture.get(AndroidDeviceScriptFixtureInfoProvider.SKYLARK_CONSTRUCTOR);
    assertThat(deviceScriptFixtureInfoProvider).isNotNull();
    assertThat(deviceScriptFixtureInfoProvider.getFixtureScript()).isNotNull();
    assertThat(deviceScriptFixtureInfoProvider.getFixtureScript().prettyPrint())
        .isEqualTo("scripts/my_script.sh");
  }

  @Test
  public void testCommandFixture() throws Exception {
    scratch.file(
        "javatests/com/app/BUILD",
        "android_device_script_fixture(",
        "  name = 'fixture',",
        "  cmd = 'some literal command',",
        ")");
    ConfiguredTarget fixture = getConfiguredTarget("//javatests/com/app:fixture");
    assertThat(fixture).isNotNull();
    AndroidDeviceScriptFixtureInfoProvider deviceScriptFixtureInfoProvider =
        fixture.get(AndroidDeviceScriptFixtureInfoProvider.SKYLARK_CONSTRUCTOR);
    assertThat(deviceScriptFixtureInfoProvider).isNotNull();
    assertThat(deviceScriptFixtureInfoProvider.getFixtureScript()).isNotNull();
    assertThat(deviceScriptFixtureInfoProvider.getFixtureScript().prettyPrint())
        .isEqualTo("javatests/com/app/cmd_device_fixtures/fixture/cmd.sh");
    FileWriteAction action =
        (FileWriteAction) getGeneratingAction(deviceScriptFixtureInfoProvider.getFixtureScript());
    assertThat(action.getFileContents()).isEqualTo("some literal command");
  }

  @Test
  public void testNoScriptOrCommand() throws Exception {
    checkError(
        "javatests/com/app",
        "fixture",
        "android_host_service_fixture requires that exactly one of the script and cmd attributes "
            + "be specified",
        "android_device_script_fixture(",
        "  name = 'fixture',",
        ")");
  }

  @Test
  public void testScriptAndCommand() throws Exception {
    checkError(
        "javatests/com/app",
        "fixture",
        "android_host_service_fixture requires that exactly one of the script and cmd attributes "
            + "be specified",
        "android_device_script_fixture(",
        "  name = 'fixture',",
        "  script = '//scripts:my_script.sh',",
        "  cmd = 'some literal command',",
        ")");
  }

  @Test
  public void testSupportApks() throws Exception {
    scratch.file(
        "javatests/com/app/BUILD",
        "android_device_script_fixture(",
        "  name = 'fixture',",
        "  cmd = 'some literal command',",
        "  support_apks = [",
        "    '//java/com/app/support',",
        "    '//java/com/app/support:generated.apk',",
        "  ],",
        ")");
    ConfiguredTarget fixture = getConfiguredTarget("//javatests/com/app:fixture");
    assertThat(fixture).isNotNull();
    AndroidDeviceScriptFixtureInfoProvider deviceScriptFixtureInfoProvider =
        fixture.get(AndroidDeviceScriptFixtureInfoProvider.SKYLARK_CONSTRUCTOR);
    assertThat(deviceScriptFixtureInfoProvider).isNotNull();

    assertThat(
            ActionsTestUtil.prettyArtifactNames(deviceScriptFixtureInfoProvider.getSupportApks()))
        .containsExactly("java/com/app/support/support.apk", "java/com/app/support/generated.apk")
        .inOrder();
  }

  @Test
  public void testNonSupportedScriptExtension() throws Exception {
    scratch.file("javatests/com/app/script.bat");
    checkError(
        "javatests/com/app",
        "fixture",
        "file '//javatests/com/app:script.bat' is misplaced here (expected .sh)",
        "android_device_script_fixture(",
        "  name = 'fixture',",
        "  script = 'script.bat',",
        ")");
  }

  @Test
  public void testDaemonIsProvided() throws Exception {
    scratch.file(
        "javatests/com/app/BUILD",
        "android_device_script_fixture(",
        "  name = 'fixture',",
        "  cmd = 'some literal command',",
        "  daemon = 1,",
        ")");
    ConfiguredTarget fixture = getConfiguredTarget("//javatests/com/app:fixture");
    assertThat(fixture).isNotNull();
    AndroidDeviceScriptFixtureInfoProvider deviceScriptFixtureInfoProvider =
        fixture.get(AndroidDeviceScriptFixtureInfoProvider.SKYLARK_CONSTRUCTOR);
    assertThat(deviceScriptFixtureInfoProvider).isNotNull();
    assertThat(deviceScriptFixtureInfoProvider.getDaemon()).isTrue();
  }

  @Test
  public void testStrictExitIsProvided() throws Exception {
    scratch.file(
        "javatests/com/app/BUILD",
        "android_device_script_fixture(",
        "  name = 'fixture',",
        "  cmd = 'some literal command',",
        "  strict_exit = 1,",
        ")");
    ConfiguredTarget fixture = getConfiguredTarget("//javatests/com/app:fixture");
    assertThat(fixture).isNotNull();
    AndroidDeviceScriptFixtureInfoProvider deviceScriptFixtureInfoProvider =
        fixture.get(AndroidDeviceScriptFixtureInfoProvider.SKYLARK_CONSTRUCTOR);
    assertThat(deviceScriptFixtureInfoProvider).isNotNull();
    assertThat(deviceScriptFixtureInfoProvider.getStrictExit()).isTrue();
  }
}
