// 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 "starboard/shared/widevine/widevine_storage.h"

#include "starboard/file.h"
#include "starboard/log.h"
#include "starboard/types.h"

namespace starboard {
namespace shared {
namespace widevine {

namespace {

void ReadFile(const std::string& path_name, std::vector<uint8_t>* content) {
  SB_DCHECK(content);

  ScopedFile file(path_name.c_str(), kSbFileOpenOnly | kSbFileRead);

  if (!file.IsValid()) {
    content->clear();
    SB_LOG(INFO) << "Failed to open " << path_name
                 << ", returning empty content.";
    return;
  }

  auto size = file.GetSize();
  if (size < 0) {
    content->clear();
    SB_LOG(INFO) << "Failed to get size of " << path_name
                 << ", returning empty content.";
    return;
  }

  content->resize(size);
  if (file.ReadAll(reinterpret_cast<char*>(content->data()), size) != size) {
    content->clear();
    SB_LOG(INFO) << "Failed to read content of " << path_name
                 << ", returning empty content.";
    return;
  }
}

bool WriteFile(const std::string& path_name,
               const std::vector<uint8_t>& content) {
  ScopedFile file(path_name.c_str(), kSbFileCreateAlways | kSbFileWrite);

  if (!file.IsValid()) {
    SB_LOG(INFO) << "Failed to create " << path_name << " for writing.";
    return false;
  }

  if (file.WriteAll(reinterpret_cast<const char*>(content.data()),
                    static_cast<int>(content.size())) != content.size()) {
    SB_LOG(INFO) << "Failed to write content to " << path_name << '.';
    return false;
  }

  file.Flush();

  return true;
}

bool ReadString(const std::vector<uint8_t>& data,
                size_t* offset,
                std::string* str) {
  if (*offset + sizeof(int) > data.size()) {
    SB_LOG(ERROR) << "Failed to read the size of string from |data|.";
    return false;
  }
  int size = *reinterpret_cast<const int*>(data.data() + *offset);
  *offset += sizeof(int);
  if (*offset + size > data.size()) {
    SB_LOG(ERROR) << "Failed to read " << size << " bytes from |data|.";
    return false;
  }
  str->assign(reinterpret_cast<const char*>(data.data() + *offset),
              reinterpret_cast<const char*>(data.data() + *offset + size));
  *offset += size;
  return true;
}

void WriteString(const std::string& str, std::vector<uint8_t>* content) {
  content->reserve(content->size() + sizeof(int) + str.size());
  content->resize(content->size() + sizeof(int));
  *reinterpret_cast<int*>(content->data() + content->size() - sizeof(int)) =
      static_cast<int>(str.size());
  content->insert(content->end(), reinterpret_cast<const uint8_t*>(str.c_str()),
                  reinterpret_cast<const uint8_t*>(str.c_str()) + str.size());
}

}  // namespace

WidevineStorage::WidevineStorage(const std::string& path_name)
    : path_name_(path_name) {
  std::vector<uint8_t> content;
  ReadFile(path_name_, &content);
  size_t offset = 0;

  while (offset != content.size()) {
    std::string name, value;
    if (!ReadString(content, &offset, &name) ||
        !ReadString(content, &offset, &value)) {
      cache_.clear();
      SB_LOG(WARNING) << path_name_ << " is corrupt, returns empty content.";
      return;
    }
    cache_[name] = value;
  }

  SB_LOG(INFO) << "Loaded " << cache_.size() << " records from " << path_name_;
}

bool WidevineStorage::read(const std::string& name, std::string* data) {
  SB_DCHECK(data);
  ScopedLock scoped_lock(lock_);
  auto iter = cache_.find(name);
  if (iter == cache_.end()) {
    return false;
  }
  *data = iter->second;
  return true;
}

bool WidevineStorage::write(const std::string& name, const std::string& data) {
  ScopedLock scoped_lock(lock_);
  cache_[name] = data;

  std::vector<uint8_t> content;
  for (auto iter : cache_) {
    WriteString(iter.first, &content);
    WriteString(iter.second, &content);
  }

  return WriteFile(path_name_, content);
}

bool WidevineStorage::exists(const std::string& name) {
  ScopedLock scoped_lock(lock_);
  return cache_.find(name) != cache_.end();
}

bool WidevineStorage::remove(const std::string& name) {
  ScopedLock scoped_lock(lock_);
  auto iter = cache_.find(name);
  if (iter == cache_.end()) {
    return false;
  }
  cache_.erase(iter);
  return true;
}

int32_t WidevineStorage::size(const std::string& name) {
  ScopedLock scoped_lock(lock_);
  auto iter = cache_.find(name);
  return iter == cache_.end() ? -1 : static_cast<int32_t>(iter->second.size());
}

bool WidevineStorage::list(std::vector<std::string>* records) {
  SB_DCHECK(records);
  ScopedLock scoped_lock(lock_);
  records->clear();
  for (auto item : cache_) {
    records->push_back(item.first);
  }
  return !records->empty();
}

}  // namespace widevine
}  // namespace shared
}  // namespace starboard
