// Copyright 2018 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/overlay_info/overlay_info_registry.h"

#include "base/logging.h"
#include "base/memory/singleton.h"
#include "starboard/common/mutex.h"
#include "starboard/common/string.h"

namespace cobalt {
namespace overlay_info {
namespace {

const auto kDelimiter = OverlayInfoRegistry::kDelimiter;

class OverlayInfoRegistryImpl {
 public:
  static OverlayInfoRegistryImpl* GetInstance();

  void Disable();

  void Register(const char* category, const char* str);
  void Register(const char* category, const void* data, size_t data_size);
  void RetrieveAndClear(std::vector<uint8_t>* infos);

 private:
  // Reserve enough data for |infos_| to avoid extra allcations.
  static const size_t kReservedSize = 4096;

  OverlayInfoRegistryImpl() = default;

  // To make our private constructor available to
  // base::Singleton<OverlayInfoRegistryImpl,
  // DefaultSingletonTraits<OverlayInfoRegistryImpl>>.
  friend struct base::DefaultSingletonTraits<OverlayInfoRegistryImpl>;

  bool enabled_ = true;
  starboard::Mutex mutex_;
  std::vector<uint8_t> infos_;
};

// static
OverlayInfoRegistryImpl* OverlayInfoRegistryImpl::GetInstance() {
  return base::Singleton<
      OverlayInfoRegistryImpl,
      base::DefaultSingletonTraits<OverlayInfoRegistryImpl>>::get();
}

void OverlayInfoRegistryImpl::Disable() {
  starboard::ScopedLock scoped_lock(mutex_);
  enabled_ = false;
  infos_.clear();
}

void OverlayInfoRegistryImpl::Register(const char* category, const char* str) {
  auto length = SbStringGetLength(str);
  Register(category, reinterpret_cast<const uint8_t*>(str), length);
}

void OverlayInfoRegistryImpl::Register(const char* category, const void* data,
                                       size_t data_size) {
  DCHECK(SbStringFindCharacter(
             category, static_cast<char>(OverlayInfoRegistry::kDelimiter)) ==
         NULL)
      << "Category " << category
      << " cannot contain the delimiter:" << OverlayInfoRegistry::kDelimiter;
  auto category_size = SbStringGetLength(category);
  auto total_size = category_size + 1 + data_size;

  DCHECK_GT(category_size, 0u);
  // Use |kMaxSizeOfData + 0| to avoid link error caused by DCHECK_LE.
  DCHECK_LE(total_size, OverlayInfoRegistry::kMaxSizeOfData + 0);

  starboard::ScopedLock scoped_lock(mutex_);
  // Use |kMaxNumberOfPendingOverlayInfo + 0| to avoid link error caused by
  // DCHECK_LE.
  DCHECK_LE(infos_.size() + total_size,
            OverlayInfoRegistry::kMaxNumberOfPendingOverlayInfo + 0);
  if (enabled_) {
    infos_.push_back(static_cast<uint8_t>(total_size));
    infos_.insert(infos_.end(), category, category + category_size);
    infos_.push_back(kDelimiter);
    infos_.insert(infos_.end(), static_cast<const uint8_t*>(data),
                  static_cast<const uint8_t*>(data) + data_size);
  }
}

void OverlayInfoRegistryImpl::RetrieveAndClear(std::vector<uint8_t>* infos) {
  DCHECK(infos);

  starboard::ScopedLock scoped_lock(mutex_);
  if (enabled_) {
    infos->swap(infos_);
    infos_.clear();
    infos_.reserve(kReservedSize);
  }
}

}  // namespace

void OverlayInfoRegistry::Disable() {
  OverlayInfoRegistryImpl::GetInstance()->Disable();
}

void OverlayInfoRegistry::Register(const char* category, const char* str) {
  OverlayInfoRegistryImpl::GetInstance()->Register(category, str);
}

void OverlayInfoRegistry::Register(const char* category, const void* data,
                                   size_t data_size) {
  OverlayInfoRegistryImpl::GetInstance()->Register(category, data, data_size);
}

void OverlayInfoRegistry::RetrieveAndClear(std::vector<uint8_t>* infos) {
  OverlayInfoRegistryImpl::GetInstance()->RetrieveAndClear(infos);
}

}  // namespace overlay_info
}  // namespace cobalt
