/*
 * 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.
 */

#ifndef COBALT_RENDERER_RENDER_TREE_PIXEL_TESTER_H_
#define COBALT_RENDERER_RENDER_TREE_PIXEL_TESTER_H_

#include "base/file_path.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "cobalt/math/size.h"
#include "cobalt/render_tree/node.h"
#include "cobalt/renderer/backend/graphics_context.h"
#include "cobalt/renderer/backend/graphics_system.h"
#include "cobalt/renderer/backend/render_target.h"
#include "cobalt/renderer/rasterizer/rasterizer.h"

namespace cobalt {
namespace renderer {

// The render tree pixel tester allows one to compare the output of a rasterized
// render tree with a saved expected ground truth version of the output image.
// The ground truth images are stored in filenames based off of the root
// expected results directory passed into the constructor, and a relative path
// provided on each call to TestTree().
class RenderTreePixelTester {
 public:
  struct Options {
    Options();

    // Determines the size of the Gaussian that will be convolved
    // with the actual and expected image before they are compared.
    float gaussian_blur_sigma;

    // Determines the range of error for each color channel that we are willing
    // to accept when we declare a actual pixel is equal to an expected pixel.
    float acceptable_channel_range;

    // If enabled, it will result in the output of the actual image, expected
    // output image, and a diff image that highlights any differing regions for
    // all tests that fail.
    bool output_failed_test_details;

    // Similar to output_failed_test_details, but if this flag is enabled, even
    // passing tests will have their details output.  This might be useful to
    // inspect if there are differences that are not caught by the tests because
    // of the image fuzzing (Gaussian blur + error range) that occurs within
    // these tests.
    bool output_all_test_details;
  };

  // Setups up a render tree pixel tester context.  The pixel tests will occur
  // on a test surface of test_surface_dimensions dimensions.  All expected
  // output will be seeked for within the expected_results_directory directory.
  // If rebaselining or outputting test details, this output will appear in
  // output_directory.
  RenderTreePixelTester(const math::Size& test_surface_dimensions,
                        const FilePath& expected_results_directory,
                        const FilePath& output_directory,
                        const Options& options);
  ~RenderTreePixelTester();

  // Given a render tree and a base filename, rasterizes the render tree and
  // saves it as the expected output file in the directory rooted at
  // output_directory passed into the constructor.
  void Rebaseline(const scoped_refptr<cobalt::render_tree::Node>& test_tree,
                  const FilePath& expected_base_filename) const;

  // Given the passed in render tree and based on the expected output
  // found in a file based on expected_base_filename and
  // expected_results_directory (passed in via the constructor), returns if
  // the rasterized render tree matches the expected output.  Depending
  // on options passed in to the constructor (e.g. output_failed_test_details),
  // this method may have the side-effect of outputting files that describe the
  // details of the comparison (e.g. expected and actual output).
  bool TestTree(const scoped_refptr<cobalt::render_tree::Node>& test_tree,
                const FilePath& expected_base_filename) const;

  render_tree::ResourceProvider* GetResourceProvider() const;

 private:
  scoped_array<uint8_t> RasterizeRenderTree(
      const scoped_refptr<cobalt::render_tree::Node>& test_tree) const;

  scoped_ptr<cobalt::renderer::backend::GraphicsSystem> graphics_system_;
  scoped_ptr<cobalt::renderer::backend::GraphicsContext> graphics_context_;
  scoped_ptr<cobalt::renderer::rasterizer::Rasterizer> rasterizer_;
  scoped_refptr<cobalt::renderer::backend::RenderTarget> test_surface_;

  FilePath expected_results_directory_;
  FilePath output_directory_;

  Options options_;
};

}  // namespace renderer
}  // namespace cobalt

#endif  // COBALT_RENDERER_RENDER_TREE_PIXEL_TESTER_H_
