// Copyright 2016 The Cobalt 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.

#ifndef COBALT_RENDER_TREE_MOCK_RESOURCE_PROVIDER_H_
#define COBALT_RENDER_TREE_MOCK_RESOURCE_PROVIDER_H_

#include <memory>
#include <string>
#include <vector>

#include "base/memory/ref_counted.h"
#include "cobalt/render_tree/font.h"
#include "cobalt/render_tree/font_provider.h"
#include "cobalt/render_tree/glyph_buffer.h"
#include "cobalt/render_tree/image.h"
#include "cobalt/render_tree/lottie_animation.h"
#include "cobalt/render_tree/node.h"
#include "cobalt/render_tree/resource_provider.h"
#include "cobalt/render_tree/typeface.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cobalt {
namespace render_tree {

class MockResourceProvider : public ResourceProvider {
 public:
  // Comment out override in order to enable
  // "-Winconsistent-missing-override" on Clang.  TODO: Remove this hack once
  // gmock adds override support.
  virtual base::TypeId GetTypeId() const /*override*/ {
    return base::GetTypeId<MockResourceProvider>();
  }

  MOCK_METHOD0(Finish, void());
  MOCK_METHOD1(PixelFormatSupported, bool(PixelFormat pixel_format));
  MOCK_METHOD1(AlphaFormatSupported, bool(AlphaFormat alpha_format));
  MOCK_METHOD3(AllocateImageDataMock,
               ImageData*(const math::Size& size, PixelFormat pixel_format,
                          AlphaFormat alpha_format));
  MOCK_METHOD1(CreateImageMock, Image*(ImageData* pixel_data));
  MOCK_METHOD2(AllocateRawImageMemoryMock,
               RawImageMemory*(size_t size_in_bytes, size_t alignment));
  MOCK_METHOD2(CreateMultiPlaneImageFromRawMemoryMock,
               Image*(RawImageMemory* raw_image_memory,
                      const MultiPlaneImageDataDescriptor& descriptor));
  MOCK_CONST_METHOD1(HasLocalFontFamily, bool(const char* font_family_name));
  MOCK_METHOD2(GetLocalTypefaceMock,
               Typeface*(const char* font_family_name, FontStyle font_style));
  MOCK_METHOD0(LoadAdditionalFonts, void());
  MOCK_METHOD1(GetLocalTypefaceIfAvailableMock,
               Typeface*(const std::string& font_face_name));
  MOCK_METHOD3(GetCharacterFallbackTypefaceMock,
               Typeface*(int32 utf32_character, FontStyle font_style,
                         const std::string& language));
  MOCK_METHOD2(CreateTypefaceFromRawDataMock,
               Typeface*(RawTypefaceDataVector* raw_data,
                         std::string* error_string));
  MOCK_METHOD5(CreateGlyphBufferMock,
               render_tree::GlyphBuffer*(
                   const base::char16* text_buffer, size_t text_length,
                   const std::string& language, bool is_rtl,
                   render_tree::FontProvider* font_provider));
  MOCK_METHOD2(
      CreateGlyphBufferMock,
      render_tree::GlyphBuffer*(const std::string& utf8_string,
                                const scoped_refptr<render_tree::Font>& font));
  MOCK_METHOD6(GetTextWidth,
               float(const base::char16* text_buffer, size_t text_length,
                     const std::string& language, bool is_rtl,
                     render_tree::FontProvider* font_provider,
                     render_tree::FontVector* maybe_used_fonts));

  MOCK_METHOD2(CreateLottieAnimationMock,
               LottieAnimation*(const char* data, size_t length));

  MOCK_METHOD2(CreateMeshMock,
               render_tree::Mesh*(std::vector<render_tree::Mesh::Vertex>*,
                                  render_tree::Mesh::DrawMode));

  MOCK_METHOD1(DrawOffscreenImage,
               scoped_refptr<render_tree::Image>(
                   const scoped_refptr<render_tree::Node>& root));

  std::unique_ptr<ImageData> AllocateImageData(const math::Size& size,
                                               PixelFormat pixel_format,
                                               AlphaFormat alpha_format) {
    return std::unique_ptr<ImageData>(
        AllocateImageDataMock(size, pixel_format, alpha_format));
  }
  scoped_refptr<Image> CreateImage(std::unique_ptr<ImageData> pixel_data) {
    return scoped_refptr<Image>(CreateImageMock(pixel_data.get()));
  }

  scoped_refptr<Image> CreateImageFromSbDecodeTarget(SbDecodeTarget target) {
    return NULL;
  }

  bool SupportsSbDecodeTarget() { return false; }

  SbDecodeTargetGraphicsContextProvider*
  GetSbDecodeTargetGraphicsContextProvider() {
    return NULL;
  }

  std::unique_ptr<RawImageMemory> AllocateRawImageMemory(size_t size_in_bytes,
                                                         size_t alignment) {
    return std::unique_ptr<RawImageMemory>(
        AllocateRawImageMemoryMock(size_in_bytes, alignment));
  }
  scoped_refptr<Image> CreateMultiPlaneImageFromRawMemory(
      std::unique_ptr<RawImageMemory> raw_image_memory,
      const MultiPlaneImageDataDescriptor& descriptor) {
    return scoped_refptr<Image>(CreateMultiPlaneImageFromRawMemoryMock(
        raw_image_memory.get(), descriptor));
  }
  scoped_refptr<Typeface> GetLocalTypeface(const char* font_family_name,
                                           FontStyle font_style) {
    return scoped_refptr<Typeface>(
        GetLocalTypefaceMock(font_family_name, font_style));
  }
  scoped_refptr<Typeface> GetLocalTypefaceByFaceNameIfAvailable(
      const char* font_face_name) {
    return scoped_refptr<Typeface>(
        GetLocalTypefaceIfAvailableMock(font_face_name));
  }
  scoped_refptr<Typeface> GetCharacterFallbackTypeface(
      int32 utf32_character, FontStyle font_style,
      const std::string& language) {
    return scoped_refptr<Typeface>(GetCharacterFallbackTypefaceMock(
        utf32_character, font_style, language));
  }
  scoped_refptr<Typeface> CreateTypefaceFromRawData(
      std::unique_ptr<RawTypefaceDataVector> raw_data,
      std::string* error_string) {
    return scoped_refptr<Typeface>(
        CreateTypefaceFromRawDataMock(raw_data.get(), error_string));
  }
  scoped_refptr<render_tree::GlyphBuffer> CreateGlyphBuffer(
      const base::char16* text_buffer, size_t text_length,
      const std::string& language, bool is_rtl,
      render_tree::FontProvider* font_provider) {
    return scoped_refptr<render_tree::GlyphBuffer>(CreateGlyphBufferMock(
        text_buffer, text_length, language, is_rtl, font_provider));
  }
  scoped_refptr<render_tree::GlyphBuffer> CreateGlyphBuffer(
      const std::string& utf8_string,
      const scoped_refptr<render_tree::Font>& font) {
    return scoped_refptr<render_tree::GlyphBuffer>(
        CreateGlyphBufferMock(utf8_string, font.get()));
  }
  scoped_refptr<LottieAnimation> CreateLottieAnimation(const char* data,
                                                       size_t length) {
    return scoped_refptr<LottieAnimation>(
        CreateLottieAnimationMock(data, length));
  }

  virtual scoped_refptr<Mesh> CreateMesh(
      std::unique_ptr<std::vector<Mesh::Vertex> > vertices,
      Mesh::DrawMode draw_mode) {
    return base::WrapRefCounted(CreateMeshMock(vertices.get(), draw_mode));
  }
};

}  // namespace render_tree
}  // namespace cobalt

#endif  // COBALT_RENDER_TREE_MOCK_RESOURCE_PROVIDER_H_
