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

#include "cobalt/browser/memory_settings/auto_mem.h"

#include <string>
#include <vector>

#include "base/optional.h"
#include "cobalt/browser/memory_settings/auto_mem_settings.h"
#include "cobalt/browser/memory_settings/calculations.h"
#include "cobalt/browser/memory_settings/test_common.h"
#include "cobalt/browser/switches.h"
#include "cobalt/math/size.h"
#include "starboard/system.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cobalt {
namespace browser {
namespace memory_settings {
namespace {

const math::Size kResolution1080p(1920, 1080);

// Represents what the cobalt engine can scale down to under a default
// environment.
const int64_t kSmallEngineCpuMemorySize = 130 * 1024 * 1024;

const int64_t kSmallEngineGpuMemorySize = 68 * 1024 * 1024;

#define EXPECT_MEMORY_SETTING(SETTING, SOURCE, MEMORY_TYPE, VALUE)          \
  EXPECT_EQ(VALUE, SETTING->value()) << " failure for " << SETTING->name(); \
  EXPECT_EQ(MEMORY_TYPE, SETTING->memory_type()) << "failure for "          \
                                                 << SETTING->memory_type(); \
  EXPECT_EQ(SOURCE, SETTING->source_type()) << " failure for "              \
                                            << SETTING->name();

AutoMemSettings EmptyCommandLine() {
  return AutoMemSettings(AutoMemSettings::kTypeCommandLine);
}

scoped_ptr<AutoMem> CreateDefaultAutoMem() {
  AutoMemSettings build_settings(AutoMemSettings::kTypeBuild);
  scoped_ptr<AutoMem> auto_mem(
      new AutoMem(kResolution1080p, EmptyCommandLine(), build_settings));
  return auto_mem.Pass();
}

}  // namespace.

// Tests the expectation that the command-line overrides will be applied.
// Settings which are enabled/disabled when blitter is enabled/disabled are
// also tested.
TEST(AutoMem, CommandLineOverrides) {
  // Load up command line settings of command lines.
  AutoMemSettings command_line_settings(AutoMemSettings::kTypeCommandLine);
  command_line_settings.cobalt_image_cache_size_in_bytes = 1234;
  command_line_settings.javascript_garbage_collection_threshold_in_bytes = 2345;
  command_line_settings.skia_cache_size_in_bytes = 3456;
  command_line_settings.skia_texture_atlas_dimensions =
      TextureDimensions(1234, 5678, 2);
  command_line_settings.software_surface_cache_size_in_bytes = 4567;
  command_line_settings.offscreen_target_cache_size_in_bytes = 5678;

  for (int i = 0; i <= 1; ++i) {
    AutoMemSettings build_settings = GetDefaultBuildSettings();
    build_settings.has_blitter = (i == 0);

    AutoMem auto_mem(kResolution1080p, command_line_settings, build_settings);

    // image_cache_size_in_bytes and javascript_gc_threshold_in_bytes settings
    // ignore the blitter type.
    EXPECT_MEMORY_SETTING(auto_mem.image_cache_size_in_bytes(),
                          MemorySetting::kCmdLine, MemorySetting::kGPU, 1234);

    EXPECT_MEMORY_SETTING(auto_mem.javascript_gc_threshold_in_bytes(),
                          MemorySetting::kCmdLine, MemorySetting::kCPU, 2345);

    if (auto_mem.offscreen_target_cache_size_in_bytes()->valid()) {
      EXPECT_MEMORY_SETTING(auto_mem.offscreen_target_cache_size_in_bytes(),
                            MemorySetting::kCmdLine, MemorySetting::kGPU, 5678);
    }

    // Certain features are only available for the blitter, and some features
    // are disabled, vice versa.
    if (build_settings.has_blitter) {
      // When blitter is active then skia_atlas_texture_dimensions are
      // not applicable because this is an OpenGl egl feature.
      EXPECT_MEMORY_SETTING(
          auto_mem.skia_atlas_texture_dimensions(), MemorySetting::kCmdLine,
          MemorySetting::kNotApplicable, TextureDimensions(0, 0, 0));
      // Skia cache is also an egl-only feature, which is not applicable
      // for blitter.
      EXPECT_MEMORY_SETTING(auto_mem.skia_cache_size_in_bytes(),
                            MemorySetting::kCmdLine,
                            MemorySetting::kNotApplicable, 0);

      EXPECT_MEMORY_SETTING(auto_mem.software_surface_cache_size_in_bytes(),
                            MemorySetting::kCmdLine, MemorySetting::kCPU, 4567);
    } else {
      // Skia atlas is an egl-only feature and therefore enabled.
      EXPECT_MEMORY_SETTING(auto_mem.skia_atlas_texture_dimensions(),
                            MemorySetting::kCmdLine, MemorySetting::kGPU,
                            TextureDimensions(1234, 5678, 2));

      // Skia cache is an egl-only feature therefore it is enabled for egl.
      EXPECT_MEMORY_SETTING(auto_mem.skia_cache_size_in_bytes(),
                            MemorySetting::kCmdLine, MemorySetting::kGPU, 3456);

      // Software surface cache is a blitter-only feature, therefore disabled
      // in egl.
      EXPECT_MEMORY_SETTING(auto_mem.software_surface_cache_size_in_bytes(),
                            MemorySetting::kCmdLine,
                            MemorySetting::kNotApplicable, 0);
    }
  }
}

// Tests the expectation that if the command line specifies that the variable
// is "autoset" that the builtin setting is overriden.
TEST(AutoMem, CommandLineSpecifiesAutoset) {
  AutoMemSettings command_line_settings(AutoMemSettings::kTypeCommandLine);
  command_line_settings.cobalt_image_cache_size_in_bytes = -1;
  AutoMemSettings build_settings(AutoMemSettings::kTypeBuild);
  build_settings.cobalt_image_cache_size_in_bytes = 1234;

  AutoMem auto_mem(kResolution1080p, command_line_settings, build_settings);

  EXPECT_MEMORY_SETTING(auto_mem.image_cache_size_in_bytes(),
                        MemorySetting::kAutoSet, MemorySetting::kGPU,
                        CalculateImageCacheSize(kResolution1080p));
}

// Tests that skia atlas texture will be bind to the built in value, iff it has
// been set.
TEST(AutoMem, SkiaGlyphAtlasTextureSize) {
  AutoMemSettings build_settings(AutoMemSettings::kTypeBuild);
  AutoMemSettings build_settings_with_default(AutoMemSettings::kTypeBuild);

  build_settings_with_default.skia_texture_atlas_dimensions =
      TextureDimensions(1234, 5678, 2);

  AutoMem auto_mem(kResolution1080p, EmptyCommandLine(), build_settings);
  AutoMem auto_mem_with_default(kResolution1080p, EmptyCommandLine(),
                                build_settings_with_default);

  // Expect that when the skia_atlas_texture_dimensions is specified in the
  // build settings that it will bind to the auto-set value (computed from
  // CalculateSkiaGlyphAtlasTextureSize(...)).
  EXPECT_MEMORY_SETTING(auto_mem.skia_atlas_texture_dimensions(),
                        MemorySetting::kAutoSet, MemorySetting::kGPU,
                        CalculateSkiaGlyphAtlasTextureSize(kResolution1080p));

  // Expect that when the skia_atlas_texture_dimensions is specified in the
  // build settings that it will bind to the final value.
  EXPECT_MEMORY_SETTING(auto_mem_with_default.skia_atlas_texture_dimensions(),
                        MemorySetting::kBuildSetting, MemorySetting::kGPU,
                        TextureDimensions(1234, 5678, 2));
}

// Tests that software surface cache will be bind to the built in value, iff
// it has been set.
TEST(AutoMem, SoftwareSurfaceCacheSizeInBytes) {
  AutoMemSettings build_settings(AutoMemSettings::kTypeBuild);
  AutoMemSettings build_settings_with_default(AutoMemSettings::kTypeBuild);
  // Enable the setting by enabling the blitter.
  build_settings.has_blitter = true;
  build_settings_with_default.has_blitter = true;
  build_settings_with_default.software_surface_cache_size_in_bytes = 1234;

  AutoMem auto_mem(kResolution1080p, EmptyCommandLine(), build_settings);
  AutoMem auto_mem_with_surface_cache(kResolution1080p, EmptyCommandLine(),
                                      build_settings_with_default);

  // Expect that when the software_surface_cache_size_in_bytes is specified in
  // the/ build settings that it will bind to the auto-set value (computed from
  // CalculateSoftwareSurfaceCacheSizeInBytes(...)).
  EXPECT_MEMORY_SETTING(
      auto_mem.software_surface_cache_size_in_bytes(), MemorySetting::kAutoSet,
      MemorySetting::kCPU,
      CalculateSoftwareSurfaceCacheSizeInBytes(kResolution1080p));

  EXPECT_MEMORY_SETTING(
      auto_mem_with_surface_cache.software_surface_cache_size_in_bytes(),
      MemorySetting::kBuildSetting, MemorySetting::kCPU, 1234);
}

// Tests that skia cache will be bind to the built in value, iff
// it has been set.
TEST(AutoMem, SkiaCacheSizeInBytes) {
  AutoMemSettings build_settings(AutoMemSettings::kTypeBuild);
  AutoMemSettings build_settings_with_default(AutoMemSettings::kTypeBuild);
  build_settings_with_default.skia_cache_size_in_bytes = 1234;

  AutoMem auto_mem(kResolution1080p, EmptyCommandLine(), build_settings);
  AutoMem auto_mem_with_skia_cache(kResolution1080p, EmptyCommandLine(),
                                   build_settings_with_default);

  EXPECT_MEMORY_SETTING(auto_mem.skia_cache_size_in_bytes(),
                        MemorySetting::kAutoSet, MemorySetting::kGPU,
                        CalculateSkiaCacheSize(kResolution1080p));

  EXPECT_MEMORY_SETTING(auto_mem_with_skia_cache.skia_cache_size_in_bytes(),
                        MemorySetting::kBuildSetting, MemorySetting::kGPU,
                        1234);
}

TEST(AutoMem, AllMemorySettingsAreOrderedByName) {
  AutoMemSettings build_settings(AutoMemSettings::kTypeBuild);

  AutoMem auto_mem(kResolution1080p, EmptyCommandLine(), build_settings);

  std::vector<const MemorySetting*> settings = auto_mem.AllMemorySettings();

  for (size_t i = 1; i < settings.size(); ++i) {
    ASSERT_LT(settings[i-1]->name(), settings[i]->name());
  }
}

// Tests the expectation that constraining the CPU memory to kSmallEngineSize
// will result in AutoMem reducing to the expected memory footprint.
TEST(AutoMem, ConstrainedCPUEnvironment) {
  AutoMemSettings build_settings(AutoMemSettings::kTypeBuild);
  build_settings.max_cpu_in_bytes = kSmallEngineCpuMemorySize;

  AutoMem auto_mem(kResolution1080p, EmptyCommandLine(), build_settings);

  const int64_t cpu_memory_consumption =
      auto_mem.SumAllMemoryOfType(MemorySetting::kCPU);
  EXPECT_LE(cpu_memory_consumption, kSmallEngineCpuMemorySize);
}

// Tests the expectation that constraining the GPU memory will result
// in AutoMem reducing the the memory footprint.
TEST(AutoMem, ConstrainedGPUEnvironment) {
  AutoMemSettings build_settings(AutoMemSettings::kTypeBuild);
  build_settings.max_gpu_in_bytes = 57 * 1024 * 1024;
  AutoMem auto_mem(kResolution1080p, EmptyCommandLine(), build_settings);

  std::vector<const MemorySetting*> settings = auto_mem.AllMemorySettings();
  const int64_t gpu_memory_consumption =
      SumMemoryConsumption(MemorySetting::kGPU, settings);
  EXPECT_LE(gpu_memory_consumption, *build_settings.max_gpu_in_bytes);
}

// Tests the expectation that constraining the CPU memory to 40MB will result
// in AutoMem reducing the the memory footprint.
TEST(AutoMem, ExplicitReducedCPUMemoryConsumption) {
  // STEP ONE: Get the "natural" size of the engine at the default test
  // settings.
  scoped_ptr<AutoMem> default_auto_mem = CreateDefaultAutoMem();

  AutoMemSettings command_line_settings(AutoMemSettings::kTypeCommandLine);
  command_line_settings.reduce_cpu_memory_by = 5 * 1024 * 1024;
  AutoMemSettings build_settings(AutoMemSettings::kTypeBuild);
  AutoMem reduced_cpu_memory_auto_mem(kResolution1080p, command_line_settings,
                                      build_settings);

  EXPECT_EQ(5 * 1024 * 1024,
            reduced_cpu_memory_auto_mem.reduced_cpu_bytes_->value());

  const int64_t original_memory_consumption =
      default_auto_mem->SumAllMemoryOfType(MemorySetting::kCPU);
  const int64_t reduced_memory_consumption =
      reduced_cpu_memory_auto_mem.SumAllMemoryOfType(MemorySetting::kCPU);

  EXPECT_LE(5 * 1024 * 1024,
            original_memory_consumption - reduced_memory_consumption);
}

// Tests the expectation that constraining the CPU memory to 40MB will result
// in AutoMem reducing the the memory footprint.
TEST(AutoMem, ExplicitReducedGPUMemoryConsumption) {
  // STEP ONE: Get the "natural" size of the engine at the default test
  // settings.
  scoped_ptr<AutoMem> default_auto_mem = CreateDefaultAutoMem();

  AutoMemSettings command_line_settings(AutoMemSettings::kTypeCommandLine);
  command_line_settings.reduce_gpu_memory_by = 5 * 1024 * 1024;
  AutoMemSettings build_settings(AutoMemSettings::kTypeBuild);
  AutoMem reduced_cpu_memory_auto_mem(kResolution1080p, command_line_settings,
                                      build_settings);
  EXPECT_EQ(5 * 1024 * 1024,
            reduced_cpu_memory_auto_mem.reduced_gpu_bytes_->value());

  const int64_t original_memory_consumption =
      default_auto_mem->SumAllMemoryOfType(MemorySetting::kGPU);
  const int64_t reduced_memory_consumption =
      reduced_cpu_memory_auto_mem.SumAllMemoryOfType(MemorySetting::kGPU);

  EXPECT_LE(5 * 1024 * 1024,
            original_memory_consumption - reduced_memory_consumption);
}

// Tests the expectation that the max cpu value is ignored when reducing
// memory.
TEST(AutoMem, MaxCpuIsIgnoredDuringExplicitMemoryReduction) {
  // STEP ONE: Get the "natural" size of the engine at the default test
  // settings.
  scoped_ptr<AutoMem> default_auto_mem = CreateDefaultAutoMem();

  AutoMemSettings command_line_settings(AutoMemSettings::kTypeCommandLine);
  command_line_settings.reduce_cpu_memory_by = 5 * 1024 * 1024;
  AutoMemSettings build_settings(AutoMemSettings::kTypeBuild);
  build_settings.max_cpu_in_bytes = 1;
  AutoMem reduced_cpu_memory_auto_mem(kResolution1080p, command_line_settings,
                                      build_settings);

  EXPECT_EQ(5 * 1024 * 1024,
            reduced_cpu_memory_auto_mem.reduced_cpu_bytes_->value());

  const int64_t original_memory_consumption =
      default_auto_mem->SumAllMemoryOfType(MemorySetting::kCPU);
  const int64_t reduced_memory_consumption =
      reduced_cpu_memory_auto_mem.SumAllMemoryOfType(MemorySetting::kCPU);

  // Max_cpu_in_bytes specifies one byte of memory, but reduce must override
  // this for this test to pass.
  EXPECT_LE(5 * 1024 * 1024,
            original_memory_consumption - reduced_memory_consumption);
}

// Tests the expectation that the constrainer will not run on cpu memory if
// --reduce_cpu_memory_by is set to 0.
TEST(AutoMem, MaxCpuIsIgnoredWithZeroValueReduceCPUCommand) {
  // STEP ONE: Get the "natural" size of the engine at the default test
  // settings.
  scoped_ptr<AutoMem> default_auto_mem = CreateDefaultAutoMem();

  AutoMemSettings command_line_settings(AutoMemSettings::kTypeCommandLine);
  AutoMemSettings build_settings(AutoMemSettings::kTypeBuild);

  // Max memory is 1-byte. We expect that the kReduceCpuMemoryBy = "0" will
  // override the max_cpu_in_bytes setting.
  build_settings.max_cpu_in_bytes = 1;
  command_line_settings.reduce_cpu_memory_by = 0;

  AutoMem auto_mem_no_reduce_cpu(kResolution1080p, command_line_settings,
                                 build_settings);

  const int64_t original_memory_consumption =
      default_auto_mem->SumAllMemoryOfType(MemorySetting::kCPU);
  const int64_t new_memory_consumption =
      auto_mem_no_reduce_cpu.SumAllMemoryOfType(MemorySetting::kCPU);

  // Max_cpu_in_bytes specifies one byte of memory, but reduce must override
  // this for this test to pass.
  EXPECT_EQ(original_memory_consumption, new_memory_consumption);
}

// Tests the expectation that the constrainer will not run on gpu memory if
// --reduce_gpu_memory_by is set to 0.
TEST(AutoMem, MaxCpuIsIgnoredWithZeroValueReduceGPUCommand) {
  // STEP ONE: Get the "natural" size of the engine at the default test
  // settings.
  scoped_ptr<AutoMem> default_auto_mem = CreateDefaultAutoMem();

  AutoMemSettings command_line_settings(AutoMemSettings::kTypeCommandLine);
  AutoMemSettings build_settings(AutoMemSettings::kTypeBuild);

  // Max memory is 1-byte. We expect that the kReduceCpuMemoryBy = "0" will
  // override the max_cpu_in_bytes setting.
  build_settings.max_gpu_in_bytes = 1;
  command_line_settings.reduce_gpu_memory_by = 0;

  AutoMem auto_mem_no_reduce_cpu(kResolution1080p, command_line_settings,
                                 build_settings);

  const int64_t original_memory_consumption =
      default_auto_mem->SumAllMemoryOfType(MemorySetting::kGPU);
  const int64_t new_memory_consumption =
      auto_mem_no_reduce_cpu.SumAllMemoryOfType(MemorySetting::kGPU);

  // Max_gpu_in_bytes specifies one byte of memory, but reduce must override
  // this for this test to pass.
  EXPECT_EQ(original_memory_consumption, new_memory_consumption);
}

// Tests the expectation that if --reduce_cpu_memory_by is set to -1 that it
// will be effectively disabled and --max_cpu_bytes be used as the memory
// reduction means.
TEST(AutoMem, MaxCpuIsEnabledWhenReduceCpuMemoryIsExplicitlyDisabled) {
  AutoMemSettings command_line_settings(AutoMemSettings::kTypeCommandLine);
  AutoMemSettings build_settings(AutoMemSettings::kTypeBuild);

  // Max memory is 1-byte. We expect that the kReduceCpuMemoryBy = "-1"
  // passed to the command line will cause max_cpu_in_bytes to be the
  // dominating memory reduction mechanism.
  build_settings.max_cpu_in_bytes = kSmallEngineGpuMemorySize;
  command_line_settings.reduce_cpu_memory_by = -1;

  AutoMem auto_mem_no_reduce_cpu(kResolution1080p, command_line_settings,
                                 build_settings);
  const int64_t memory_consumption =
      auto_mem_no_reduce_cpu.SumAllMemoryOfType(MemorySetting::kCPU);
  // Max_cpu_in_bytes specifies one byte of memory, but reduce must override
  // this for this test to pass.
  EXPECT_LE(memory_consumption, kSmallEngineCpuMemorySize);
}

// Tests the expectation that if --reduce_gpu_memory_by is set to -1 that it
// will be effectively disabled and --max_gpu_bytes be used as the memory
// reduction means.
TEST(AutoMem, MaxGpuIsEnabledWhenReduceCpuMemoryIsExplicitlyDisabled) {
  AutoMemSettings command_line_settings(AutoMemSettings::kTypeCommandLine);
  AutoMemSettings build_settings(AutoMemSettings::kTypeBuild);

  // Max memory is 1-byte. We expect that the kReduceCpuMemoryBy = "-1"
  // passed to the command line will cause max_cpu_in_bytes to be the
  // dominating memory reduction mechanism.
  build_settings.max_gpu_in_bytes = kSmallEngineGpuMemorySize;
  command_line_settings.reduce_gpu_memory_by = -1;

  AutoMem auto_mem_no_reduce_cpu(kResolution1080p, command_line_settings,
                                 build_settings);
  const int64_t memory_consumption =
      auto_mem_no_reduce_cpu.SumAllMemoryOfType(MemorySetting::kGPU);
  // Max_cpu_in_bytes specifies one byte of memory, but reduce must override
  // this for this test to pass.
  EXPECT_LE(memory_consumption, kSmallEngineGpuMemorySize);
}

// Tests that if the gpu memory could not be queried then the resulting
// max_gpu_bytes will not be valid.
TEST(AutoMem, NoDefaultGpuMemory) {
  AutoMemSettings command_line_settings(AutoMemSettings::kTypeCommandLine);
  AutoMemSettings build_settings(AutoMemSettings::kTypeBuild);

  AutoMem auto_mem(kResolution1080p, command_line_settings,
                   build_settings);

  EXPECT_EQ(SbSystemHasCapability(kSbSystemCapabilityCanQueryGPUMemoryStats),
            auto_mem.max_gpu_bytes()->valid());
}

}  // namespace memory_settings
}  // namespace browser
}  // namespace cobalt

#undef EXPECT_MEMORY_SETTING
