// Copyright 2015 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.actions;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static com.google.devtools.build.lib.actions.util.ActionsTestUtil.NULL_ACTION_OWNER;
import static org.junit.Assert.fail;

import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.actions.util.DummyExecutor;
import com.google.devtools.build.lib.analysis.actions.ExecutableSymlinkAction;
import com.google.devtools.build.lib.exec.SingleBuildFileCache;
import com.google.devtools.build.lib.testutil.Scratch;
import com.google.devtools.build.lib.testutil.TestFileOutErr;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.Path;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Test cases for {@link ExecutableSymlinkAction}. */
@RunWith(JUnit4.class)
public class ExecutableSymlinkActionTest {
  private Scratch scratch = new Scratch();
  private Root inputRoot;
  private Root outputRoot;
  TestFileOutErr outErr;
  private Executor executor;

  @Before
  public final void createExecutor() throws Exception  {
    final Path inputDir = scratch.dir("/in");
    inputRoot = Root.asDerivedRoot(inputDir);
    outputRoot = Root.asDerivedRoot(scratch.dir("/out"));
    outErr = new TestFileOutErr();
    executor = new DummyExecutor(scratch.getFileSystem(), inputDir);
  }

  private ActionExecutionContext createContext() {
    Path execRoot = executor.getExecRoot();
    return new ActionExecutionContext(
        executor,
        new SingleBuildFileCache(execRoot.getPathString(), execRoot.getFileSystem()),
        ActionInputPrefetcher.NONE,
        null, outErr, ImmutableMap.<String, String>of(), null);
  }

  @Test
  public void testSimple() throws Exception {
    Path inputFile = inputRoot.getPath().getChild("some-file");
    Path outputFile = outputRoot.getPath().getChild("some-output");
    FileSystemUtils.createEmptyFile(inputFile);
    inputFile.setExecutable(/*executable=*/true);
    Artifact input = new Artifact(inputFile, inputRoot);
    Artifact output = new Artifact(outputFile, outputRoot);
    ExecutableSymlinkAction action = new ExecutableSymlinkAction(NULL_ACTION_OWNER, input, output);
    ActionResult actionResult = action.execute(createContext());
    assertThat(actionResult.spawnResults()).isEmpty();
    assertThat(outputFile.resolveSymbolicLinks()).isEqualTo(inputFile);
  }

  @Test
  public void testFailIfInputIsNotAFile() throws Exception {
    Path dir = inputRoot.getPath().getChild("some-dir");
    FileSystemUtils.createDirectoryAndParents(dir);
    Artifact input = new Artifact(dir, inputRoot);
    Artifact output = new Artifact(outputRoot.getPath().getChild("some-output"), outputRoot);
    ExecutableSymlinkAction action = new ExecutableSymlinkAction(NULL_ACTION_OWNER, input, output);
    try {
      action.execute(createContext());
      fail();
    } catch (ActionExecutionException e) {
      assertThat(e).hasMessageThat().contains("'some-dir' is not a file");
    }
  }

  @Test
  public void testFailIfInputIsNotExecutable() throws Exception {
    Path file = inputRoot.getPath().getChild("some-file");
    FileSystemUtils.createEmptyFile(file);
    file.setExecutable(/*executable=*/false);
    Artifact input = new Artifact(file, inputRoot);
    Artifact output = new Artifact(outputRoot.getPath().getChild("some-output"), outputRoot);
    ExecutableSymlinkAction action = new ExecutableSymlinkAction(NULL_ACTION_OWNER, input, output);
    try {
      action.execute(createContext());
      fail();
    } catch (ActionExecutionException e) {
      String want = "'some-file' is not executable";
      String got = e.getMessage();
      assertWithMessage(String.format("got %s, want %s", got, want))
          .that(got.contains(want))
          .isTrue();
    }
  }
}
