/*
 * Copyright 2013-present Facebook, Inc.
 *
 * 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.facebook.buck.java;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import com.facebook.buck.testutil.integration.DebuggableTemporaryFolder;
import com.facebook.buck.testutil.integration.ProjectWorkspace;
import com.facebook.buck.testutil.integration.TestDataHelper;
import com.google.common.base.Charsets;
import com.google.common.io.Files;

import org.junit.Rule;
import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;

public class CachedTestRunReportingIntegrationTest {

  private final static Charset CHARSET_FOR_TEST = Charsets.UTF_8;

  @Rule
  public DebuggableTemporaryFolder tmp = new DebuggableTemporaryFolder();

  /**
   * Test that we correctly report which test runs are cached.
   */
  @Test
  public void testCachedTestRun() throws IOException {
    tmp.delete();
    ProjectWorkspace workspace = TestDataHelper.createProjectWorkspaceForScenario(
        this, "cached_test", tmp);
    workspace.setUp();

    // No caching for this run.
    assertFalse(
        "There should not be any caching for the initial test run.",
        isTestRunCached(workspace, true));

    // Cached Results.
    assertTrue(
        "A second test run without any modifications should be cached.",
        isTestRunCached(workspace, true));

    // Make the test fail.
    File testFile = workspace.getFile("LameTest.java");
    String originalJavaCode = Files.toString(testFile, CHARSET_FOR_TEST);
    String failingJavaCode = originalJavaCode.replace("String str = \"I am not null.\";",
        "String str = null;");
    Files.write(failingJavaCode, testFile, CHARSET_FOR_TEST);

    // No caching for this run.
    assertFalse(
        "There should not be any caching for this test run.",
        isTestRunCached(workspace, false));

    // Cached Results.
    assertTrue(
        "A second test run without any modifications should be cached.",
        isTestRunCached(workspace, false));
  }

  private boolean isTestRunCached(ProjectWorkspace workspace, boolean expectSuccess)
      throws IOException {
    ProjectWorkspace.ProcessResult result = workspace.runBuckCommand("test", "//:test");
    workspace.verify();
    result.assertExitCode(expectSuccess ? 0 : 1);
    // Test that Test status is reported
    assertTrue(result.getStderr().contains("com.example.LameTest"));
    String status = expectSuccess ? "PASS CACHED" : "FAIL CACHED";
    return result.getStderr().contains(status);
  }
}
