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

#ifndef COBALT_BROWSER_MEMORY_SETTINGS_MEMORY_SETTINGS_H_
#define COBALT_BROWSER_MEMORY_SETTINGS_MEMORY_SETTINGS_H_

#include <map>
#include <string>
#include <vector>

#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/optional.h"
#include "cobalt/browser/memory_settings/scaling_function.h"
#include "cobalt/browser/memory_settings/texture_dimensions.h"
#include "cobalt/math/size.h"
#include "starboard/configuration.h"
#include "starboard/types.h"

namespace cobalt {
namespace browser {
namespace memory_settings {

// An abstract MemorySetting. Subclasses will implement how the class parses
// string values.
class MemorySetting {
 public:
  virtual ~MemorySetting() {}
  // SourceType defines the location where the setting was set from.
  // kNotApplicable means the setting is not supported on the current system
  // configuration.
  enum SourceType {
    kUnset,
    kStarboardAPI,
    kCmdLine,
    kAutoSet,
    kAutosetConstrained
  };
  enum ClassType { kInt, kDimensions };
  enum MemoryType { kCPU, kGPU, kNotApplicable };

  // Stringify's the value of this memory setting.
  virtual std::string ValueToString() const = 0;

  // Returns the memory consumption (in bytes) that the memory setting will
  // be allocated.
  virtual int64_t MemoryConsumption() const = 0;

  // Sets the memory scaling function. This will control whether this
  // MemorySetting will allow it's memory to be adjusted. If this is not
  // set then ComputeAbsoluteMemoryScale(...) will return 1.0 for all inputs
  // values, indicating that it can't be adjusted.
  void set_memory_scaling_function(ScalingFunction function);

  // Computes the absolute memory scale value from the requested_memory_scale.
  // The absolute memory scale can be multiplied against MemoryConsumption()
  // to predict the new memory consumption. This prediction should match the
  // actual memory consumption after ScaleMemory(memory_scale) is called.
  double ComputeAbsoluteMemoryScale(double requested_memory_scale) const;

  // Adjusts the memory by the percentage passed in. Note that the base value
  // is adjusted and repeatedly calling this function will repeatedly adjust
  // this value. For example, calling AdjustMemory(.5) twice will reduce the
  // memory by 25%.
  //
  // Calling this function will automatically set the source_type to
  // kAutosetConstrained.
  //
  // Note that the expectation here is that the memory scale passed in was
  // generated from ComputeAbsoluteMemoryScale().
  virtual void ScaleMemory(double memory_scale) = 0;

  // Setting kNotApplicable will invalidate the MemorySetting.
  void set_memory_type(MemoryType memory_type) { memory_type_ = memory_type; }
  const std::string& name() const { return name_; }
  SourceType source_type() const { return source_type_; }
  ClassType class_type() const { return class_type_; }
  MemoryType memory_type() const { return memory_type_; }

  bool valid() const {
    return (kNotApplicable != memory_type_) && (kUnset != source_type_);
  }

 protected:
  MemorySetting(ClassType type, const std::string& name);

  const ClassType class_type_;
  const std::string name_;
  SourceType source_type_;
  MemoryType memory_type_;  // Defaults to kCPU.
  ScalingFunction memory_scaling_function_;

 private:
  // Default constructor for MemorySetting is forbidden. Do not use it.
  MemorySetting();
  MemorySetting(const MemorySetting&) = delete;
  void operator=(const MemorySetting&) = delete;
};

// A memory setting for integer values.
class IntSetting : public MemorySetting {
 public:
  explicit IntSetting(const std::string& name);

  std::string ValueToString() const override;
  int64_t MemoryConsumption() const override;
  void ScaleMemory(double absolute_constraining_value) override;

  int64_t value() const { return valid() ? value_ : 0; }
  base::Optional<int64_t> optional_value() const {
    base::Optional<int64_t> output;
    if (valid()) {
      output = value_;
    }
    return output;
  }
  void set_value(SourceType source_type, int64_t val) {
    source_type_ = source_type;
    value_ = val;
  }

 private:
  int64_t value_;

  IntSetting(const IntSetting&) = delete;
  void operator=(const IntSetting&) = delete;
};

// A memory setting for dimensions type values like "2048x4096x2" where
// the first value is width, second is height, and third is bytes_per_pixel.
class DimensionSetting : public MemorySetting {
 public:
  explicit DimensionSetting(const std::string& name);

  std::string ValueToString() const override;
  int64_t MemoryConsumption() const override;

  TextureDimensions value() const {
    return valid() ? value_ : TextureDimensions();
  }
  base::Optional<TextureDimensions> optional_value() const {
    base::Optional<TextureDimensions> output;
    if (valid()) {
      output = value_;
    }
    return output;
  }

  void set_value(SourceType source_type, const TextureDimensions& val) {
    source_type_ = source_type;
    value_ = val;
  }

 private:
  TextureDimensions value_;

  DimensionSetting(const DimensionSetting&) = delete;
  void operator=(const DimensionSetting&) = delete;
};

class SkiaGlyphAtlasTextureSetting : public DimensionSetting {
 public:
  SkiaGlyphAtlasTextureSetting();
  void ScaleMemory(double absolute_constraining_value) override;

 private:
  static size_t NumberOfReductions(double reduction_factor);
};

int64_t SumMemoryConsumption(
    base::Optional<MemorySetting::MemoryType> memory_type_filter,
    const std::vector<const MemorySetting*>& memory_settings);

int64_t SumMemoryConsumption(
    base::Optional<MemorySetting::MemoryType> memory_type_filter,
    const std::vector<MemorySetting*>& memory_settings);

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

#endif  // COBALT_BROWSER_MEMORY_SETTINGS_MEMORY_SETTINGS_H_
