/*
 * Copyright 2017 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/browser/memory_settings/calculations.h"

#include "base/command_line.h"
#include "base/logging.h"
#include "cobalt/browser/memory_settings/constants.h"
#include "cobalt/browser/memory_settings/test_common.h"
#include "cobalt/browser/switches.h"
#include "starboard/log.h"
#include "starboard/memory.h"
#include "starboard/system.h"

#include "testing/gtest/include/gtest/gtest.h"

namespace cobalt {
namespace browser {
namespace memory_settings {

///////////////////////////////////
//
//            WIDTH | HEIGHT
// -------------------------
// 8K:        7,680 x 4,320
// Cinema 4K: 4,096 x 2,160
// 4k/UHD:    3,840 x 2,160
// 2K:        2,560 x 1,440
// WUXGA:     1,920 x 1,200
// 1080p:     1,920 x 1,080
// 720p:      1,280 x 720
// 480p:        640 x 480
enum StandardDisplaySettings {
  k8k,
  kCinema4k,
  kUHD4k,
  k2k,
  kWUXGA,
  k1080p,
  k720p,
  k480p
};

math::Size GetDimensions(StandardDisplaySettings enum_value) {
  switch (enum_value) {
    case k8k: {
      return math::Size(7680, 4320);
    }
    case kCinema4k: {
      return math::Size(4096, 2160);
    }
    case kUHD4k: {
      return math::Size(3840, 2160);
    }
    case k2k: {
      return math::Size(2560, 1440);
    }
    case kWUXGA: {
      return math::Size(1920, 1200);
    }
    case k1080p: {
      return math::Size(1920, 1080);
    }
    case k720p: {
      return math::Size(1280, 720);
    }
    case k480p: {
      return math::Size(640, 480);
    }
  }

  EXPECT_TRUE(false) << "Should not be reached. Unknown enum_value: "
                     << enum_value;
  return GetDimensions(k1080p);
}

// Tests the expectation that CalculateImageCacheSize() is a pure function
// (side effect free) and will produce the expected results.
TEST(MemoryCalculations, CalculateImageCacheSize) {
  EXPECT_EQ(kMinImageCacheSize, CalculateImageCacheSize(GetDimensions(k720p)));
  EXPECT_EQ(32 * 1024 * 1024,  // 32MB.
            CalculateImageCacheSize(GetDimensions(k1080p)));
  EXPECT_EQ(kMaxImageCacheSize, CalculateImageCacheSize(GetDimensions(kUHD4k)));

  // Expect that the floor is hit for smaller values.
  EXPECT_EQ(kMinImageCacheSize, CalculateImageCacheSize(GetDimensions(k480p)));

  // Expect that the ceiling is hit for larger values.
  EXPECT_EQ(kMaxImageCacheSize,
            CalculateImageCacheSize(GetDimensions(kCinema4k)));
  EXPECT_EQ(kMaxImageCacheSize, CalculateImageCacheSize(GetDimensions(k8k)));
}

// Tests the expectation that CalculateSkiaGlyphAtlasTextureSize() is a pure
// function (side effect free) and will produce expected results.
TEST(MemoryCalculations, CalculateSkiaGlyphAtlasTextureSize) {
  math::Size ui_dimensions;
  TextureDimensions atlas_texture_size;

  // Test that the small resolution of 480p produces a texture atlas
  // that is minimal.
  ui_dimensions = GetDimensions(k480p);
  atlas_texture_size = CalculateSkiaGlyphAtlasTextureSize(ui_dimensions);
  EXPECT_EQ(kMinSkiaGlyphTextureAtlasWidth, atlas_texture_size.width());
  EXPECT_EQ(kMinSkiaGlyphTextureAtlasHeight, atlas_texture_size.height());

  // Test that expected resolution of 1080p produces a 2048x2048
  // atlas texture.
  ui_dimensions = GetDimensions(k1080p);
  atlas_texture_size = CalculateSkiaGlyphAtlasTextureSize(ui_dimensions);
  EXPECT_EQ(2048, atlas_texture_size.width());
  EXPECT_EQ(2048, atlas_texture_size.height());

  // Test that expected resolution of 4k produces a 8192x4096
  // atlas texture.
  ui_dimensions = GetDimensions(kUHD4k);
  atlas_texture_size = CalculateSkiaGlyphAtlasTextureSize(ui_dimensions);
  EXPECT_EQ(8192, atlas_texture_size.width());
  EXPECT_EQ(4096, atlas_texture_size.height());

  // Test that ultra-high 8k resolution produces expected results.
  ui_dimensions = GetDimensions(k8k);
  atlas_texture_size = CalculateSkiaGlyphAtlasTextureSize(ui_dimensions);
  EXPECT_EQ(16384, atlas_texture_size.width());
  EXPECT_EQ(16384, atlas_texture_size.height());
}

TEST(MemoryCalculations, CalculateSoftwareSurfaceCacheSizeInBytes) {
  math::Size ui_resolution = GetDimensions(k720p);
  // Expect that a 720p resolution produces a 4mb SoftwareSurfaceCache.
  EXPECT_EQ(4 * 1024 * 1024,
            CalculateSoftwareSurfaceCacheSizeInBytes(ui_resolution));

  ui_resolution = GetDimensions(k1080p);
  // Expect that a 1080p resolution produces a 9mb SoftwareSurfaceCache.
  EXPECT_EQ(9 * 1024 * 1024,
            CalculateSoftwareSurfaceCacheSizeInBytes(ui_resolution));
}

TEST(MemoryCalculations, CalculateMiscCobaltGpuSize) {
  math::Size ui_resolution = GetDimensions(k1080p);
  EXPECT_EQ(24 * 1024 * 1024,
            CalculateMiscCobaltGpuSize(ui_resolution));
}

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