/*
 * Copyright 2015 Google Inc. 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.
 */

#include "cobalt/renderer/rasterizer/pixel_test_fixture.h"

#include <string>

#include "base/command_line.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "cobalt/base/cobalt_paths.h"

namespace cobalt {
namespace renderer {
namespace rasterizer {

namespace switches {
// Command line switches.

// If enabled, running the tests will result in the generation of expected
// test output from the actual output to the output directory.
const char kRebaseline[] = "rebaseline";

// If enabled, will run all tests and display which ones passed and which
// ones failed, as usual, however it will also output new expected output
// images for ONLY the tests that failed.
const char kRebaselineFailedTests[] = "rebaseline-failed-tests";

// If enabled, will output details (in the form of files placed in the output
// directory) for all tests that fail.
const char kOutputFailedTestDetails[] = "output-failed-test-details";

// Like kOutputFailedTestDetails, but outputs details for tests that
// succeed as well.
const char kOutputAllTestDetails[] = "output-all-test-details";
}  // namespace switches

namespace {
// Specifies the size of all test render targets, in pixels.
const int kTestSurfaceWidth = 200;
const int kTestSurfaceHeight = 200;

// Returns the directory that all test output files should be placed in (e.g.
// when kRebaseline, kOutputFailedTestDetails, or
// kOutputAllTestDetails switches are set).
FilePath GetTestOutputDirectory() {
  FilePath out_file_dir;
  PathService::Get(cobalt::paths::DIR_COBALT_TEST_OUT, &out_file_dir);
  out_file_dir = out_file_dir.Append(FILE_PATH_LITERAL("cobalt"))
                     .Append(FILE_PATH_LITERAL("renderer"))
                     .Append(FILE_PATH_LITERAL("rasterizer"))
                     .Append(FILE_PATH_LITERAL("testdata"));

  return out_file_dir;
}

// Returns the directory that all input expected results test data files should
// be found in. Files should be placed in this location by the build process.
FilePath GetTestInputDirectory() {
  FilePath in_file_dir;
  PathService::Get(base::DIR_SOURCE_ROOT, &in_file_dir);
  return in_file_dir.Append(FILE_PATH_LITERAL("cobalt"))
      .Append(FILE_PATH_LITERAL("renderer"))
      .Append(FILE_PATH_LITERAL("rasterizer"))
      .Append(FILE_PATH_LITERAL("testdata"));
}

}  // namespace

PixelTest::PixelTest() {
  // Create a render tree pixel tester object based on options specified
  // by command-line parameters and compile time constants defined in this
  // file.
  RenderTreePixelTester::Options pixel_tester_options;
  pixel_tester_options.output_failed_test_details =
      CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kOutputFailedTestDetails);
  pixel_tester_options.output_all_test_details =
      CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kOutputAllTestDetails);

  pixel_tester_.emplace(math::Size(kTestSurfaceWidth, kTestSurfaceHeight),
                        GetTestInputDirectory(), GetTestOutputDirectory(),
                        pixel_tester_options);

  output_surface_size_ = math::Size(kTestSurfaceWidth, kTestSurfaceHeight);
}

PixelTest::~PixelTest() {}

void PixelTest::TestTree(
    const scoped_refptr<cobalt::render_tree::Node>& test_tree) {
  // First extract the current test's name into a std::string so that we
  // can use it to load and save image files associated with this test.
  std::string current_test_name(
      ::testing::UnitTest::GetInstance()->current_test_info()->name());

  bool results =
      pixel_tester_->TestTree(test_tree, FilePath(current_test_name));
  EXPECT_TRUE(results);

  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kRebaseline) ||
      (!results &&
       CommandLine::ForCurrentProcess()->HasSwitch(
           switches::kRebaselineFailedTests))) {
    // If the 'rebase' flag is set, we should not run any actual tests but
    // instead output the results of our tests so that they can be used as
    // expected output for subsequent tests.
    pixel_tester_->Rebaseline(test_tree, FilePath(current_test_name));
  }
}

}  // namespace rasterizer
}  // namespace renderer
}  // namespace cobalt
