// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "modules/cachestorage/InspectorCacheStorageAgent.h"

#include "platform/heap/Handle.h"
#include "platform/weborigin/KURL.h"
#include "platform/weborigin/SecurityOrigin.h"
#include "public/platform/Platform.h"
#include "public/platform/WebSecurityOrigin.h"
#include "public/platform/WebString.h"
#include "public/platform/WebURL.h"
#include "public/platform/WebVector.h"
#include "public/platform/modules/serviceworker/WebServiceWorkerCache.h"
#include "public/platform/modules/serviceworker/WebServiceWorkerCacheError.h"
#include "public/platform/modules/serviceworker/WebServiceWorkerCacheStorage.h"
#include "public/platform/modules/serviceworker/WebServiceWorkerRequest.h"
#include "public/platform/modules/serviceworker/WebServiceWorkerResponse.h"
#include "wtf/Noncopyable.h"
#include "wtf/PassRefPtr.h"
#include "wtf/PtrUtil.h"
#include "wtf/RefCounted.h"
#include "wtf/RefPtr.h"
#include "wtf/Vector.h"
#include "wtf/text/StringBuilder.h"
#include <algorithm>
#include <memory>

using blink::protocol::Array;
using blink::protocol::CacheStorage::Cache;
using blink::protocol::CacheStorage::DataEntry;

typedef blink::protocol::CacheStorage::Backend::DeleteCacheCallback
    DeleteCacheCallback;
typedef blink::protocol::CacheStorage::Backend::DeleteEntryCallback
    DeleteEntryCallback;
typedef blink::protocol::CacheStorage::Backend::RequestCacheNamesCallback
    RequestCacheNamesCallback;
typedef blink::protocol::CacheStorage::Backend::RequestEntriesCallback
    RequestEntriesCallback;
typedef blink::WebServiceWorkerCache::BatchOperation BatchOperation;

namespace blink {

namespace {

String buildCacheId(const String& securityOrigin, const String& cacheName) {
  String id(securityOrigin);
  id.append('|');
  id.append(cacheName);
  return id;
}

bool parseCacheId(ErrorString* errorString,
                  const String& id,
                  String* securityOrigin,
                  String* cacheName) {
  size_t pipe = id.find('|');
  if (pipe == WTF::kNotFound) {
    *errorString = "Invalid cache id.";
    return false;
  }
  *securityOrigin = id.substring(0, pipe);
  *cacheName = id.substring(pipe + 1);
  return true;
}

std::unique_ptr<WebServiceWorkerCacheStorage> assertCacheStorage(
    ErrorString* errorString,
    const String& securityOrigin) {
  RefPtr<SecurityOrigin> secOrigin =
      SecurityOrigin::createFromString(securityOrigin);

  // Cache Storage API is restricted to trustworthy origins.
  if (!secOrigin->isPotentiallyTrustworthy()) {
    *errorString = secOrigin->isPotentiallyTrustworthyErrorMessage();
    return nullptr;
  }

  std::unique_ptr<WebServiceWorkerCacheStorage> cache = wrapUnique(
      Platform::current()->cacheStorage(WebSecurityOrigin(secOrigin)));
  if (!cache)
    *errorString = "Could not find cache storage.";
  return cache;
}

std::unique_ptr<WebServiceWorkerCacheStorage> assertCacheStorageAndNameForId(
    ErrorString* errorString,
    const String& cacheId,
    String* cacheName) {
  String securityOrigin;
  if (!parseCacheId(errorString, cacheId, &securityOrigin, cacheName)) {
    return nullptr;
  }
  return assertCacheStorage(errorString, securityOrigin);
}

CString serviceWorkerCacheErrorString(WebServiceWorkerCacheError error) {
  switch (error) {
    case WebServiceWorkerCacheErrorNotImplemented:
      return CString("not implemented.");
      break;
    case WebServiceWorkerCacheErrorNotFound:
      return CString("not found.");
      break;
    case WebServiceWorkerCacheErrorExists:
      return CString("cache already exists.");
      break;
    case WebServiceWorkerCacheErrorQuotaExceeded:
      return CString("quota exceeded.");
    case WebServiceWorkerCacheErrorCacheNameNotFound:
      return CString("cache not found.");
    case WebServiceWorkerCacheErrorTooLarge:
      return CString("operation too large.");
  }
  NOTREACHED();
  return "";
}

class RequestCacheNames
    : public WebServiceWorkerCacheStorage::CacheStorageKeysCallbacks {
  WTF_MAKE_NONCOPYABLE(RequestCacheNames);

 public:
  RequestCacheNames(const String& securityOrigin,
                    std::unique_ptr<RequestCacheNamesCallback> callback)
      : m_securityOrigin(securityOrigin), m_callback(std::move(callback)) {}

  ~RequestCacheNames() override {}

  void onSuccess(const WebVector<WebString>& caches) override {
    std::unique_ptr<Array<Cache>> array = Array<Cache>::create();
    for (size_t i = 0; i < caches.size(); i++) {
      String name = String(caches[i]);
      std::unique_ptr<Cache> entry =
          Cache::create()
              .setSecurityOrigin(m_securityOrigin)
              .setCacheName(name)
              .setCacheId(buildCacheId(m_securityOrigin, name))
              .build();
      array->addItem(std::move(entry));
    }
    m_callback->sendSuccess(std::move(array));
  }

  void onError(WebServiceWorkerCacheError error) override {
    m_callback->sendFailure(
        String::format("Error requesting cache names: %s",
                       serviceWorkerCacheErrorString(error).data()));
  }

 private:
  String m_securityOrigin;
  std::unique_ptr<RequestCacheNamesCallback> m_callback;
};

struct DataRequestParams {
  String cacheName;
  int skipCount;
  int pageSize;
};

struct RequestResponse {
  RequestResponse() {}
  RequestResponse(const String& request, const String& response)
      : request(request), response(response) {}
  String request;
  String response;
};

class ResponsesAccumulator : public RefCounted<ResponsesAccumulator> {
  WTF_MAKE_NONCOPYABLE(ResponsesAccumulator);

 public:
  ResponsesAccumulator(int numResponses,
                       const DataRequestParams& params,
                       std::unique_ptr<RequestEntriesCallback> callback)
      : m_params(params),
        m_numResponsesLeft(numResponses),
        m_responses(static_cast<size_t>(numResponses)),
        m_callback(std::move(callback)) {}

  void addRequestResponsePair(const WebServiceWorkerRequest& request,
                              const WebServiceWorkerResponse& response) {
    ASSERT(m_numResponsesLeft > 0);
    RequestResponse& requestResponse =
        m_responses.at(m_responses.size() - m_numResponsesLeft);
    requestResponse.request = request.url().string();
    requestResponse.response = response.statusText();

    if (--m_numResponsesLeft != 0)
      return;

    std::sort(m_responses.begin(), m_responses.end(),
              [](const RequestResponse& a, const RequestResponse& b) {
                return WTF::codePointCompareLessThan(a.request, b.request);
              });
    if (m_params.skipCount > 0)
      m_responses.remove(0, m_params.skipCount);
    bool hasMore = false;
    if (static_cast<size_t>(m_params.pageSize) < m_responses.size()) {
      m_responses.remove(m_params.pageSize,
                         m_responses.size() - m_params.pageSize);
      hasMore = true;
    }
    std::unique_ptr<Array<DataEntry>> array = Array<DataEntry>::create();
    for (const auto& requestResponse : m_responses) {
      std::unique_ptr<DataEntry> entry =
          DataEntry::create()
              .setRequest(requestResponse.request)
              .setResponse(requestResponse.response)
              .build();
      array->addItem(std::move(entry));
    }
    m_callback->sendSuccess(std::move(array), hasMore);
  }

  void sendFailure(const String& error) { m_callback->sendFailure(error); }

 private:
  DataRequestParams m_params;
  int m_numResponsesLeft;
  Vector<RequestResponse> m_responses;
  std::unique_ptr<RequestEntriesCallback> m_callback;
};

class GetCacheResponsesForRequestData
    : public WebServiceWorkerCache::CacheMatchCallbacks {
  WTF_MAKE_NONCOPYABLE(GetCacheResponsesForRequestData);

 public:
  GetCacheResponsesForRequestData(const DataRequestParams& params,
                                  const WebServiceWorkerRequest& request,
                                  PassRefPtr<ResponsesAccumulator> accum)
      : m_params(params), m_request(request), m_accumulator(accum) {}
  ~GetCacheResponsesForRequestData() override {}

  void onSuccess(const WebServiceWorkerResponse& response) override {
    m_accumulator->addRequestResponsePair(m_request, response);
  }

  void onError(WebServiceWorkerCacheError error) override {
    m_accumulator->sendFailure(
        String::format("Error requesting responses for cache  %s: %s",
                       m_params.cacheName.utf8().data(),
                       serviceWorkerCacheErrorString(error).data()));
  }

 private:
  DataRequestParams m_params;
  WebServiceWorkerRequest m_request;
  RefPtr<ResponsesAccumulator> m_accumulator;
};

class GetCacheKeysForRequestData
    : public WebServiceWorkerCache::CacheWithRequestsCallbacks {
  WTF_MAKE_NONCOPYABLE(GetCacheKeysForRequestData);

 public:
  GetCacheKeysForRequestData(const DataRequestParams& params,
                             std::unique_ptr<WebServiceWorkerCache> cache,
                             std::unique_ptr<RequestEntriesCallback> callback)
      : m_params(params),
        m_cache(std::move(cache)),
        m_callback(std::move(callback)) {}
  ~GetCacheKeysForRequestData() override {}

  WebServiceWorkerCache* cache() { return m_cache.get(); }
  void onSuccess(const WebVector<WebServiceWorkerRequest>& requests) override {
    if (requests.isEmpty()) {
      std::unique_ptr<Array<DataEntry>> array = Array<DataEntry>::create();
      m_callback->sendSuccess(std::move(array), false);
      return;
    }
    RefPtr<ResponsesAccumulator> accumulator =
        adoptRef(new ResponsesAccumulator(requests.size(), m_params,
                                          std::move(m_callback)));

    for (size_t i = 0; i < requests.size(); i++) {
      const auto& request = requests[i];
      auto* cacheRequest =
          new GetCacheResponsesForRequestData(m_params, request, accumulator);
      m_cache->dispatchMatch(cacheRequest, request,
                             WebServiceWorkerCache::QueryParams());
    }
  }

  void onError(WebServiceWorkerCacheError error) override {
    m_callback->sendFailure(
        String::format("Error requesting requests for cache %s: %s",
                       m_params.cacheName.utf8().data(),
                       serviceWorkerCacheErrorString(error).data()));
  }

 private:
  DataRequestParams m_params;
  std::unique_ptr<WebServiceWorkerCache> m_cache;
  std::unique_ptr<RequestEntriesCallback> m_callback;
};

class GetCacheForRequestData
    : public WebServiceWorkerCacheStorage::CacheStorageWithCacheCallbacks {
  WTF_MAKE_NONCOPYABLE(GetCacheForRequestData);

 public:
  GetCacheForRequestData(const DataRequestParams& params,
                         std::unique_ptr<RequestEntriesCallback> callback)
      : m_params(params), m_callback(std::move(callback)) {}
  ~GetCacheForRequestData() override {}

  void onSuccess(std::unique_ptr<WebServiceWorkerCache> cache) override {
    auto* cacheRequest = new GetCacheKeysForRequestData(
        m_params, wrapUnique(cache.release()), std::move(m_callback));
    cacheRequest->cache()->dispatchKeys(cacheRequest, WebServiceWorkerRequest(),
                                        WebServiceWorkerCache::QueryParams());
  }

  void onError(WebServiceWorkerCacheError error) override {
    m_callback->sendFailure(String::format(
        "Error requesting cache %s: %s", m_params.cacheName.utf8().data(),
        serviceWorkerCacheErrorString(error).data()));
  }

 private:
  DataRequestParams m_params;
  std::unique_ptr<RequestEntriesCallback> m_callback;
};

class DeleteCache : public WebServiceWorkerCacheStorage::CacheStorageCallbacks {
  WTF_MAKE_NONCOPYABLE(DeleteCache);

 public:
  DeleteCache(std::unique_ptr<DeleteCacheCallback> callback)
      : m_callback(std::move(callback)) {}
  ~DeleteCache() override {}

  void onSuccess() override { m_callback->sendSuccess(); }

  void onError(WebServiceWorkerCacheError error) override {
    m_callback->sendFailure(
        String::format("Error requesting cache names: %s",
                       serviceWorkerCacheErrorString(error).data()));
  }

 private:
  std::unique_ptr<DeleteCacheCallback> m_callback;
};

class DeleteCacheEntry : public WebServiceWorkerCache::CacheBatchCallbacks {
  WTF_MAKE_NONCOPYABLE(DeleteCacheEntry);

 public:
  DeleteCacheEntry(std::unique_ptr<DeleteEntryCallback> callback)
      : m_callback(std::move(callback)) {}
  ~DeleteCacheEntry() override {}

  void onSuccess() override { m_callback->sendSuccess(); }

  void onError(WebServiceWorkerCacheError error) override {
    m_callback->sendFailure(
        String::format("Error requesting cache names: %s",
                       serviceWorkerCacheErrorString(error).data()));
  }

 private:
  std::unique_ptr<DeleteEntryCallback> m_callback;
};

class GetCacheForDeleteEntry
    : public WebServiceWorkerCacheStorage::CacheStorageWithCacheCallbacks {
  WTF_MAKE_NONCOPYABLE(GetCacheForDeleteEntry);

 public:
  GetCacheForDeleteEntry(const String& requestSpec,
                         const String& cacheName,
                         std::unique_ptr<DeleteEntryCallback> callback)
      : m_requestSpec(requestSpec),
        m_cacheName(cacheName),
        m_callback(std::move(callback)) {}
  ~GetCacheForDeleteEntry() override {}

  void onSuccess(std::unique_ptr<WebServiceWorkerCache> cache) override {
    auto* deleteRequest = new DeleteCacheEntry(std::move(m_callback));
    BatchOperation deleteOperation;
    deleteOperation.operationType = WebServiceWorkerCache::OperationTypeDelete;
    deleteOperation.request.setURL(KURL(ParsedURLString, m_requestSpec));
    Vector<BatchOperation> operations;
    operations.append(deleteOperation);
    cache.release()->dispatchBatch(deleteRequest,
                                   WebVector<BatchOperation>(operations));
  }

  void onError(WebServiceWorkerCacheError error) override {
    m_callback->sendFailure(String::format(
        "Error requesting cache %s: %s", m_cacheName.utf8().data(),
        serviceWorkerCacheErrorString(error).data()));
  }

 private:
  String m_requestSpec;
  String m_cacheName;
  std::unique_ptr<DeleteEntryCallback> m_callback;
};

}  // namespace

InspectorCacheStorageAgent::InspectorCacheStorageAgent() = default;

InspectorCacheStorageAgent::~InspectorCacheStorageAgent() = default;

DEFINE_TRACE(InspectorCacheStorageAgent) {
  InspectorBaseAgent::trace(visitor);
}

void InspectorCacheStorageAgent::requestCacheNames(
    const String& securityOrigin,
    std::unique_ptr<RequestCacheNamesCallback> callback) {
  RefPtr<SecurityOrigin> secOrigin =
      SecurityOrigin::createFromString(securityOrigin);

  // Cache Storage API is restricted to trustworthy origins.
  if (!secOrigin->isPotentiallyTrustworthy()) {
    // Don't treat this as an error, just don't attempt to open and enumerate
    // the caches.
    callback->sendSuccess(Array<protocol::CacheStorage::Cache>::create());
    return;
  }

  ErrorString errorString;
  std::unique_ptr<WebServiceWorkerCacheStorage> cache =
      assertCacheStorage(&errorString, securityOrigin);
  if (!cache) {
    callback->sendFailure(errorString);
    return;
  }
  cache->dispatchKeys(
      new RequestCacheNames(securityOrigin, std::move(callback)));
}

void InspectorCacheStorageAgent::requestEntries(
    const String& cacheId,
    int skipCount,
    int pageSize,
    std::unique_ptr<RequestEntriesCallback> callback) {
  ErrorString errorString;
  String cacheName;
  std::unique_ptr<WebServiceWorkerCacheStorage> cache =
      assertCacheStorageAndNameForId(&errorString, cacheId, &cacheName);
  if (!cache) {
    callback->sendFailure(errorString);
    return;
  }
  DataRequestParams params;
  params.cacheName = cacheName;
  params.pageSize = pageSize;
  params.skipCount = skipCount;
  cache->dispatchOpen(new GetCacheForRequestData(params, std::move(callback)),
                      WebString(cacheName));
}

void InspectorCacheStorageAgent::deleteCache(
    const String& cacheId,
    std::unique_ptr<DeleteCacheCallback> callback) {
  String cacheName;
  ErrorString errorString;
  std::unique_ptr<WebServiceWorkerCacheStorage> cache =
      assertCacheStorageAndNameForId(&errorString, cacheId, &cacheName);
  if (!cache) {
    callback->sendFailure(errorString);
    return;
  }
  cache->dispatchDelete(new DeleteCache(std::move(callback)),
                        WebString(cacheName));
}

void InspectorCacheStorageAgent::deleteEntry(
    const String& cacheId,
    const String& request,
    std::unique_ptr<DeleteEntryCallback> callback) {
  String cacheName;
  ErrorString errorString;
  std::unique_ptr<WebServiceWorkerCacheStorage> cache =
      assertCacheStorageAndNameForId(&errorString, cacheId, &cacheName);
  if (!cache) {
    callback->sendFailure(errorString);
    return;
  }
  cache->dispatchOpen(
      new GetCacheForDeleteEntry(request, cacheName, std::move(callback)),
      WebString(cacheName));
}

}  // namespace blink
