// Copyright 2022 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_DOM_MEDIA_SETTINGS_H_
#define COBALT_DOM_MEDIA_SETTINGS_H_

#include <string>

#include "base/optional.h"
#include "base/synchronization/lock.h"

namespace cobalt {
namespace dom {

// Holds browser wide settings for media related objects.  Their default values
// are set in related implementations, and the default values will be overridden
// if the return values of the member functions are non-empty.
// Please refer to where these functions are called for the particular
// behaviors being controlled by them.
class MediaSettings {
 public:
  virtual base::Optional<int> GetSourceBufferEvictExtraInBytes() const = 0;
  virtual base::Optional<int> GetMinimumProcessorCountToOffloadAlgorithm()
      const = 0;
  virtual base::Optional<bool> IsAsynchronousReductionEnabled() const = 0;
  virtual base::Optional<bool> IsAvoidCopyingArrayBufferEnabled() const = 0;
  virtual base::Optional<bool> IsCallingEndedWhenClosedEnabled() const = 0;
  virtual base::Optional<int> GetMaxSizeForImmediateJob() const = 0;
  virtual base::Optional<int> GetMaxSourceBufferAppendSizeInBytes() const = 0;

  virtual base::Optional<int>
  GetMediaElementTimeupdateEventIntervalInMilliseconds() const = 0;

 protected:
  MediaSettings() = default;
  ~MediaSettings() = default;

  MediaSettings(const MediaSettings&) = delete;
  MediaSettings& operator=(const MediaSettings&) = delete;
};

// Allows setting the values of MediaSource settings via a name and an int
// value.
// This class is thread safe.
class MediaSettingsImpl : public MediaSettings {
 public:
  base::Optional<int> GetSourceBufferEvictExtraInBytes() const override {
    base::AutoLock auto_lock(lock_);
    return source_buffer_evict_extra_in_bytes_;
  }
  base::Optional<int> GetMinimumProcessorCountToOffloadAlgorithm()
      const override {
    base::AutoLock auto_lock(lock_);
    return minimum_processor_count_to_offload_algorithm_;
  }
  base::Optional<bool> IsAsynchronousReductionEnabled() const override {
    base::AutoLock auto_lock(lock_);
    return is_asynchronous_reduction_enabled_;
  }
  base::Optional<bool> IsAvoidCopyingArrayBufferEnabled() const override {
    base::AutoLock auto_lock(lock_);
    return is_avoid_copying_array_buffer_enabled_;
  }
  base::Optional<bool> IsCallingEndedWhenClosedEnabled() const override {
    base::AutoLock auto_lock(lock_);
    return is_calling_ended_when_closed_enabled_;
  }
  base::Optional<int> GetMaxSizeForImmediateJob() const override {
    base::AutoLock auto_lock(lock_);
    return max_size_for_immediate_job_;
  }
  base::Optional<int> GetMaxSourceBufferAppendSizeInBytes() const override {
    base::AutoLock auto_lock(lock_);
    return max_source_buffer_append_size_in_bytes_;
  }

  base::Optional<int> GetMediaElementTimeupdateEventIntervalInMilliseconds()
      const override {
    return media_element_timeupdate_event_interval_in_milliseconds_;
  }

  // Returns true when the setting associated with `name` is set to `value`.
  // Returns false when `name` is not associated with any settings, or if
  // `value` contains an invalid value.
  bool Set(const std::string& name, int value);

 private:
  mutable base::Lock lock_;
  base::Optional<int> source_buffer_evict_extra_in_bytes_;
  base::Optional<int> minimum_processor_count_to_offload_algorithm_;
  base::Optional<bool> is_asynchronous_reduction_enabled_;
  base::Optional<bool> is_avoid_copying_array_buffer_enabled_;
  base::Optional<bool> is_calling_ended_when_closed_enabled_;
  base::Optional<int> max_size_for_immediate_job_;
  base::Optional<int> max_source_buffer_append_size_in_bytes_;

  base::Optional<int> media_element_timeupdate_event_interval_in_milliseconds_;
};

}  // namespace dom
}  // namespace cobalt

#endif  // COBALT_DOM_MEDIA_SETTINGS_H_
