/*
 * 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 <queue>
#include <set>
#include <string>
#include <unordered_map>
#include <vector>

#include "base/hash_tables.h"
#include "base/time.h"
#include "googleurl/src/gurl.h"
#include "net/http/http_request_headers.h"
#include "net/url_request/url_fetcher.h"
#include "starboard/string.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 unnesessarily expensive. We create an entry for each request and
  // If there is an old entry in the new entry's pleace 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 scoped_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_;
  base::ThreadChecker thread_checker_;
};

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