// Copyright 2015 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 <algorithm>
#include <memory>
#include <string>
#include <vector>

#include "base/files/file_util.h"
#include "base/values.h"
#include "cobalt/h5vcc/h5vcc_storage.h"
#include "cobalt/persistent_storage/persistent_settings.h"
#include "cobalt/storage/storage_manager.h"
#include "net/disk_cache/cobalt/resource_type.h"

#include "starboard/common/file.h"
#include "starboard/common/string.h"

namespace cobalt {
namespace h5vcc {

namespace {
const char kTestFileName[] = "cache_test_file.json";

const uint32 kWriteBufferSize = 1024 * 1024;

const uint32 kReadBufferSize = 1024 * 1024;

H5vccStorageWriteTestResponse WriteTestResponse(std::string error = "",
                                                uint32 bytes_written = 0) {
  H5vccStorageWriteTestResponse response;
  response.set_error(error);
  response.set_bytes_written(bytes_written);
  return response;
}

H5vccStorageVerifyTestResponse VerifyTestResponse(std::string error = "",
                                                  bool verified = false,
                                                  uint32 bytes_read = 0) {
  H5vccStorageVerifyTestResponse response;
  response.set_error(error);
  response.set_verified(verified);
  response.set_bytes_read(bytes_read);
  return response;
}

H5vccStorageSetQuotaResponse SetQuotaResponse(std::string error = "",
                                              bool success = false) {
  H5vccStorageSetQuotaResponse response;
  response.set_success(success);
  response.set_error(error);
  return response;
}

}  // namespace

H5vccStorage::H5vccStorage(
    network::NetworkModule* network_module,
    persistent_storage::PersistentSettings* persistent_settings)
    : network_module_(network_module),
      persistent_settings_(persistent_settings) {}

void H5vccStorage::ClearCookies() {
  net::CookieStore* cookie_store =
      network_module_->url_request_context()->cookie_store();
  auto* cookie_monster = static_cast<net::CookieMonster*>(cookie_store);
  network_module_->task_runner()->PostBlockingTask(
      FROM_HERE,
      base::Bind(&net::CookieMonster::DeleteAllMatchingInfoAsync,
                 base::Unretained(cookie_monster), net::CookieDeletionInfo(),
                 base::Passed(net::CookieStore::DeleteCallback())));
}

void H5vccStorage::Flush(const base::Optional<bool>& sync) {
  if (sync.value_or(false) == true) {
    DLOG(WARNING) << "Synchronous flush is not supported.";
  }

  network_module_->storage_manager()->FlushNow(base::Closure());
}

bool H5vccStorage::GetCookiesEnabled() {
  return network_module_->network_delegate()->cookies_enabled();
}

void H5vccStorage::SetCookiesEnabled(bool enabled) {
  network_module_->network_delegate()->set_cookies_enabled(enabled);
}

H5vccStorageWriteTestResponse H5vccStorage::WriteTest(uint32 test_size,
                                                      std::string test_string) {
  // Get cache_dir path.
  std::vector<char> cache_dir(kSbFileMaxPath + 1, 0);
  SbSystemGetPath(kSbSystemPathCacheDirectory, cache_dir.data(),
                  kSbFileMaxPath);

  // Delete the contents of cache_dir.
  starboard::SbFileDeleteRecursive(cache_dir.data(), true);

  // Try to Create the test_file.
  std::string test_file_path =
      std::string(cache_dir.data()) + kSbFileSepString + kTestFileName;
  SbFileError test_file_error;
  starboard::ScopedFile test_file(test_file_path.c_str(),
                                  kSbFileOpenAlways | kSbFileWrite, NULL,
                                  &test_file_error);

  if (test_file_error != kSbFileOk) {
    return WriteTestResponse(
        starboard::FormatString("SbFileError: %d while opening ScopedFile: %s",
                                test_file_error, test_file_path.c_str()));
  }

  // Repeatedly write test_string to test_size bytes of write_buffer.
  std::string write_buf;
  int iterations = test_size / test_string.length();
  for (int i = 0; i < iterations; ++i) {
    write_buf.append(test_string);
  }
  write_buf.append(test_string.substr(0, test_size % test_string.length()));

  // Incremental Writes of test_data, copies SbWriteAll, using a maximum
  // kWriteBufferSize per write.
  uint32 total_bytes_written = 0;

  do {
    auto bytes_written = test_file.Write(
        write_buf.data() + total_bytes_written,
        std::min(kWriteBufferSize, test_size - total_bytes_written));
    if (bytes_written <= 0) {
      SbFileDelete(test_file_path.c_str());
      return WriteTestResponse("SbWrite -1 return value error");
    }
    total_bytes_written += bytes_written;
  } while (total_bytes_written < test_size);

  test_file.Flush();

  return WriteTestResponse("", total_bytes_written);
}

H5vccStorageVerifyTestResponse H5vccStorage::VerifyTest(
    uint32 test_size, std::string test_string) {
  std::vector<char> cache_dir(kSbFileMaxPath + 1, 0);
  SbSystemGetPath(kSbSystemPathCacheDirectory, cache_dir.data(),
                  kSbFileMaxPath);

  std::string test_file_path =
      std::string(cache_dir.data()) + kSbFileSepString + kTestFileName;
  SbFileError test_file_error;
  starboard::ScopedFile test_file(test_file_path.c_str(),
                                  kSbFileOpenOnly | kSbFileRead, NULL,
                                  &test_file_error);

  if (test_file_error != kSbFileOk) {
    return VerifyTestResponse(
        starboard::FormatString("SbFileError: %d while opening ScopedFile: %s",
                                test_file_error, test_file_path.c_str()));
  }

  // Incremental Reads of test_data, copies SbReadAll, using a maximum
  // kReadBufferSize per write.
  uint32 total_bytes_read = 0;

  do {
    char read_buf[kReadBufferSize];
    auto bytes_read = test_file.Read(
        read_buf, std::min(kReadBufferSize, test_size - total_bytes_read));
    if (bytes_read <= 0) {
      SbFileDelete(test_file_path.c_str());
      return VerifyTestResponse("SbRead -1 return value error");
    }

    // Verify read_buf equivalent to a repeated test_string.
    for (auto i = 0; i < bytes_read; ++i) {
      if (read_buf[i] !=
          test_string[(total_bytes_read + i) % test_string.size()]) {
        return VerifyTestResponse(
            "File test data does not match with test data string");
      }
    }

    total_bytes_read += bytes_read;
  } while (total_bytes_read < test_size);

  if (total_bytes_read != test_size) {
    SbFileDelete(test_file_path.c_str());
    return VerifyTestResponse(
        "File test data size does not match kTestDataSize");
  }

  SbFileDelete(test_file_path.c_str());
  return VerifyTestResponse("", true, total_bytes_read);
}

H5vccStorageSetQuotaResponse H5vccStorage::SetQuota(
    H5vccStorageResourceTypeQuotaBytesDictionary quota) {
  if (!quota.has_other() || !quota.has_html() || !quota.has_css() ||
      !quota.has_image() || !quota.has_font() || !quota.has_splash() ||
      !quota.has_uncompiled_js() || !quota.has_compiled_js()) {
    return SetQuotaResponse(
        "H5vccStorageResourceTypeQuotaBytesDictionary input parameter missing "
        "required fields.");
  }

  if (quota.other() < 0 || quota.html() < 0 || quota.css() < 0 ||
      quota.image() < 0 || quota.font() < 0 || quota.splash() < 0 ||
      quota.uncompiled_js() < 0 || quota.compiled_js() < 0) {
    return SetQuotaResponse(
        "H5vccStorageResourceTypeQuotaBytesDictionary input parameter fields "
        "cannot "
        "have a negative value.");
  }

  auto quota_total = quota.other() + quota.html() + quota.css() +
                     quota.image() + quota.font() + quota.splash() +
                     quota.uncompiled_js() + quota.compiled_js();

  // TODO(b/235529738): Calculate correct max_quota_size that subtracts
  // non-cache memory used in the kSbSystemPathCacheDirectory.
  uint32_t max_quota_size = 24 * 1024 * 1024;
#if SB_API_VERSION >= 14
  max_quota_size = kSbMaxSystemPathCacheDirectorySize;
#endif
  if (quota_total != max_quota_size) {
    return SetQuotaResponse(starboard::FormatString(
        "H5vccStorageResourceTypeQuotaDictionary input parameter field values "
        "sum (%d) is not equal to the max cache size (%d).",
        quota_total, max_quota_size));
  }

  // Write to persistent storage with the new quota values.
  // Static cast value to double since base::Value cannot be a long.
  persistent_settings_->SetPersistentSetting(
      disk_cache::kTypeMetadata[disk_cache::kOther].directory,
      std::make_unique<base::Value>(static_cast<double>(quota.other())));
  persistent_settings_->SetPersistentSetting(
      disk_cache::kTypeMetadata[disk_cache::kHTML].directory,
      std::make_unique<base::Value>(static_cast<double>(quota.html())));
  persistent_settings_->SetPersistentSetting(
      disk_cache::kTypeMetadata[disk_cache::kCSS].directory,
      std::make_unique<base::Value>(static_cast<double>(quota.css())));
  persistent_settings_->SetPersistentSetting(
      disk_cache::kTypeMetadata[disk_cache::kImage].directory,
      std::make_unique<base::Value>(static_cast<double>(quota.image())));
  persistent_settings_->SetPersistentSetting(
      disk_cache::kTypeMetadata[disk_cache::kFont].directory,
      std::make_unique<base::Value>(static_cast<double>(quota.font())));
  persistent_settings_->SetPersistentSetting(
      disk_cache::kTypeMetadata[disk_cache::kSplashScreen].directory,
      std::make_unique<base::Value>(static_cast<double>(quota.splash())));
  persistent_settings_->SetPersistentSetting(
      disk_cache::kTypeMetadata[disk_cache::kUncompiledScript].directory,
      std::make_unique<base::Value>(
          static_cast<double>(quota.uncompiled_js())));
  persistent_settings_->SetPersistentSetting(
      disk_cache::kTypeMetadata[disk_cache::kCompiledScript].directory,
      std::make_unique<base::Value>(static_cast<double>(quota.compiled_js())));

  return SetQuotaResponse("", true);
}

H5vccStorageResourceTypeQuotaBytesDictionary H5vccStorage::GetQuota() {
  // Return persistent storage quota values.
  H5vccStorageResourceTypeQuotaBytesDictionary quota;

  auto other_meta_data = disk_cache::kTypeMetadata[disk_cache::kOther];
  quota.set_other(
      static_cast<uint32>(persistent_settings_->GetPersistentSettingAsDouble(
          other_meta_data.directory,
          other_meta_data.max_size_mb * 1024 * 1024)));

  auto html_meta_data = disk_cache::kTypeMetadata[disk_cache::kHTML];
  quota.set_html(
      static_cast<uint32>(persistent_settings_->GetPersistentSettingAsDouble(
          html_meta_data.directory, html_meta_data.max_size_mb * 1024 * 1024)));

  auto css_meta_data = disk_cache::kTypeMetadata[disk_cache::kCSS];
  quota.set_css(
      static_cast<uint32>(persistent_settings_->GetPersistentSettingAsDouble(
          css_meta_data.directory, css_meta_data.max_size_mb * 1024 * 1024)));

  auto image_meta_data = disk_cache::kTypeMetadata[disk_cache::kImage];
  quota.set_image(
      static_cast<uint32>(persistent_settings_->GetPersistentSettingAsDouble(
          image_meta_data.directory,
          image_meta_data.max_size_mb * 1024 * 1024)));

  auto font_meta_data = disk_cache::kTypeMetadata[disk_cache::kFont];
  quota.set_font(
      static_cast<uint32>(persistent_settings_->GetPersistentSettingAsDouble(
          font_meta_data.directory, font_meta_data.max_size_mb * 1024 * 1024)));

  auto splash_meta_data = disk_cache::kTypeMetadata[disk_cache::kSplashScreen];
  quota.set_splash(
      static_cast<uint32>(persistent_settings_->GetPersistentSettingAsDouble(
          splash_meta_data.directory,
          splash_meta_data.max_size_mb * 1024 * 1024)));

  auto uncompiled_meta_data =
      disk_cache::kTypeMetadata[disk_cache::kUncompiledScript];
  quota.set_uncompiled_js(
      static_cast<uint32>(persistent_settings_->GetPersistentSettingAsDouble(
          uncompiled_meta_data.directory,
          uncompiled_meta_data.max_size_mb * 1024 * 1024)));

  auto compiled_meta_data =
      disk_cache::kTypeMetadata[disk_cache::kCompiledScript];
  quota.set_compiled_js(
      static_cast<uint32>(persistent_settings_->GetPersistentSettingAsDouble(
          compiled_meta_data.directory,
          compiled_meta_data.max_size_mb * 1024 * 1024)));

  // TODO(b/235529738): Calculate correct max_quota_size that subtracts
  // non-cache memory used in the kSbSystemPathCacheDirectory.
  uint32_t max_quota_size = 24 * 1024 * 1024;
#if SB_API_VERSION >= 14
  max_quota_size = kSbMaxSystemPathCacheDirectorySize;
#endif

  quota.set_total(max_quota_size);

  return quota;
}

}  // namespace h5vcc
}  // namespace cobalt
