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

#include "cobalt/web/cache_storage.h"

#include <memory>
#include <string>
#include <utility>

#include "base/bind.h"
#include "cobalt/base/source_location.h"
#include "cobalt/cache/cache.h"
#include "cobalt/script/source_code.h"
#include "cobalt/web/context.h"
#include "cobalt/web/environment_settings_helper.h"

namespace cobalt {
namespace web {

script::Handle<script::Promise<script::Handle<script::ValueHandle>>>
CacheStorage::Match(script::EnvironmentSettings* environment_settings,
                    const script::ValueHandleHolder& request) {
  return GetOrCreateCache()->Match(environment_settings, request);
}

script::Handle<script::Promise<script::Handle<script::ValueHandle>>>
CacheStorage::Match(script::EnvironmentSettings* environment_settings,
                    const script::ValueHandleHolder& request,
                    const MultiCacheQueryOptions& options) {
  return Match(environment_settings, request);
}

void CacheStorage::PerformOpen(
    std::unique_ptr<script::ValuePromiseWrappable::Reference>
        promise_reference) {
  promise_reference->value().Resolve(GetOrCreateCache());
}

script::HandlePromiseWrappable CacheStorage::Open(
    script::EnvironmentSettings* environment_settings,
    const std::string& cache_name) {
  script::HandlePromiseWrappable promise =
      get_script_value_factory(environment_settings)
          ->CreateInterfacePromise<scoped_refptr<Cache>>();
  auto* context = get_context(environment_settings);
  context->message_loop()->task_runner()->PostTask(
      FROM_HERE,
      base::BindOnce(&CacheStorage::PerformOpen, base::Unretained(this),
                     std::make_unique<script::ValuePromiseWrappable::Reference>(
                         this, promise)));
  return promise;
}

script::HandlePromiseBool CacheStorage::Delete(
    script::EnvironmentSettings* environment_settings,
    const std::string& cache_name) {
  script::HandlePromiseBool promise =
      get_script_value_factory(environment_settings)
          ->CreateBasicPromise<bool>();
  auto promise_reference =
      std::make_unique<script::ValuePromiseBool::Reference>(this, promise);
  auto* context = get_context(environment_settings);
  context->message_loop()->task_runner()->PostTask(
      FROM_HERE, base::BindOnce(
                     [](std::unique_ptr<script::ValuePromiseBool::Reference>
                            promise_reference) {
                       cache::Cache::GetInstance()->Delete(
                           disk_cache::ResourceType::kCacheApi);
                       promise_reference->value().Resolve(true);
                     },
                     std::move(promise_reference)));
  return promise;
}

scoped_refptr<Cache> CacheStorage::GetOrCreateCache() {
  if (!cache_) {
    cache_ = new Cache();
  }
  return cache_;
}

}  // namespace web
}  // namespace cobalt
