/*
 * Copyright 2017 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.
 */

#ifndef COBALT_LOADER_CORS_PREFLIGHT_CACHE_H_
#define COBALT_LOADER_CORS_PREFLIGHT_CACHE_H_

#include <memory>
#include <queue>
#include <set>
#include <string>
#include <unordered_map>
#include <vector>

#include "base/containers/hash_tables.h"
#include "base/time/time.h"
#include "net/http/http_request_headers.h"
#include "net/url_request/url_fetcher.h"
#include "starboard/common/string.h"
#include "url/gurl.h"

namespace cobalt {
namespace loader {

// https://fetch.spec.whatwg.org/#concept-cache
class CORSPreflightCache : public base::RefCounted<CORSPreflightCache> {
 public:
  // An entry is appended at the end of every preflight to avoid same
  // preflight request in the near future.
  void AppendEntry(const std::string& url_str, const std::string& origin,
                   int max_age, bool has_credentials,
                   const std::vector<std::string>& methods_vec,
                   const std::vector<std::string>& headernames_vec);
  // Check if there is a preflight cache match. This method does not include
  // checking for CORS-safelisted method and request-header.
  bool HaveEntry(const std::string& url_str, const std::string& origin,
                 bool credentials_mode_is_include,
                 const net::URLFetcher::RequestType& new_request_method,
                 const std::vector<std::string>& unsafe_headernames);

 private:
  // Case-insensitive comparator.
  struct CaseInsensitiveCompare {
    bool operator()(const std::string& lhs, const std::string& rhs) const {
      return SbStringCompareNoCase(lhs.c_str(), rhs.c_str()) < 0;
    }
  };

  // The spec wants a cache entry for every method and for every header which is
  // a little unnecessarily expensive. We create an entry for each request and
  // If there is an old entry in the new entry's place we simply push the old
  // one out which potentially increases cache misses slightly but reduces
  // memory cost. Chromium also takes this approach.
  // The map's first key is entry's request url and second is entry's origin.
  struct CORSPreflightCacheEntry
      : public base::RefCounted<CORSPreflightCacheEntry> {
    bool credentials;
    // True if response has "Access-Control-Allow-Methods: *".
    bool allow_all_methods;
    // True if response has "Access-Control-Allow-Headers: *".
    // Non-wildcard request-header name is "Authentication".
    bool allow_all_headers_except_non_wildcard;
    base::Time expiration_time;
    std::set<net::URLFetcher::RequestType> methods;
    std::set<std::string, CaseInsensitiveCompare> headernames;

    CORSPreflightCacheEntry()
        : credentials(false),
          allow_all_methods(false),
          allow_all_headers_except_non_wildcard(false) {}
  };

  struct ExpirationHeapEntry {
    base::Time expiration_time;
    std::string url_str;
    std::string origin;
    bool operator>(const ExpirationHeapEntry& rhs) const {
      return expiration_time > rhs.expiration_time;
    }
    bool operator<(const ExpirationHeapEntry& rhs) const {
      return expiration_time < rhs.expiration_time;
    }
  };

  // This operator constructs a min-heap.
  class ExpirationMinHeapComparator {
   public:
    bool operator()(const ExpirationHeapEntry& lhs,
                    const ExpirationHeapEntry& rhs) {
      return lhs > rhs;
    }
  };

  void ClearObsoleteEntries();

  // TODO: Replace scoped_refptr with std::unique_ptr when possible or replace
  // the map as a 'scoped_map'.
  base::hash_map<
      std::string,
      base::hash_map<std::string, scoped_refptr<CORSPreflightCacheEntry> > >
      content_;

  std::priority_queue<ExpirationHeapEntry, std::vector<ExpirationHeapEntry>,
                      ExpirationMinHeapComparator>
      expiration_time_heap_;
  THREAD_CHECKER(thread_checker_);
};

}  // namespace loader
}  // namespace cobalt
#endif  // COBALT_LOADER_CORS_PREFLIGHT_CACHE_H_
