/*
 * Copyright 2017 Google Inc. 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 "base/message_loop.h"
#include "base/string_util.h"
#include "cobalt/loader/cors_preflight_cache.h"

namespace {
bool MethodNameToRequestType(const std::string& method,
                             net::URLFetcher::RequestType* request_type) {
  if (LowerCaseEqualsASCII(method, "get")) {
    *request_type = net::URLFetcher::GET;
  } else if (LowerCaseEqualsASCII(method, "post")) {
    *request_type = net::URLFetcher::POST;
  } else if (LowerCaseEqualsASCII(method, "head")) {
    *request_type = net::URLFetcher::HEAD;
  } else if (LowerCaseEqualsASCII(method, "delete")) {
    *request_type = net::URLFetcher::DELETE_REQUEST;
  } else if (LowerCaseEqualsASCII(method, "put")) {
    *request_type = net::URLFetcher::PUT;
  } else {
    return false;
  }
  return true;
}
const char* kAuthorization = "authorization";
}  // namespace

namespace cobalt {
namespace loader {

void CORSPreflightCache::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) {
  DCHECK(thread_checker_.CalledOnValidThread());
  if (max_age <= 0) {
    return;
  }
  base::TimeDelta valid_duration = base::TimeDelta::FromSeconds(max_age);
  scoped_refptr<CORSPreflightCacheEntry> new_entry =
      new CORSPreflightCacheEntry();
  new_entry->credentials = has_credentials;
  new_entry->expiration_time = base::Time::Now() + valid_duration;

  if (methods_vec.size() == 1 && methods_vec.at(0) == "*") {
    new_entry->allow_all_methods = true;
  } else {
    for (auto method : methods_vec) {
      net::URLFetcher::RequestType request_type;
      if (MethodNameToRequestType(method, &request_type)) {
        new_entry->methods.insert(request_type);
      }
    }
  }

  if (headernames_vec.size() == 1 && headernames_vec.at(0) == "*") {
    new_entry->allow_all_headers_except_non_wildcard = true;
  }
  // TODO: Consider change this function to use std::copy with std::inserter.
  // Currently compilers on some machines do not support it.
  for (auto headername : headernames_vec) {
    new_entry->headernames.insert(headername);
  }

  auto insert_result =
      content_[url_str].insert(std::make_pair(origin, new_entry));
  if (!insert_result.second) {
    insert_result.first->second = new_entry;
  }

  expiration_time_heap_.push(
      ExpirationHeapEntry{new_entry->expiration_time, url_str, origin});
}

// https://fetch.spec.whatwg.org/#concept-cache-match
bool CORSPreflightCache::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) {
  DCHECK(thread_checker_.CalledOnValidThread());
  if (url_str.empty() || origin.empty()) {
    return false;
  }
  ClearObsoleteEntries();
  // There is a cache match for request if origin is request's origin,
  // url is request's current url, either credentials is true or request's
  // credentials_mode is not "include"
  auto url_iter = content_.find(url_str);
  if (url_iter == content_.end()) {
    return false;
  }
  auto origin_iter = url_iter->second.find(origin);
  if (origin_iter == url_iter->second.end()) {
    return false;
  }
  auto entry_ptr = origin_iter->second;
  if (!entry_ptr->credentials && credentials_mode_is_include) {
    return false;
  }
  // Either last preflight's Access-Control-Allow-Methods header has * or
  // new request's method, otherwise return false.
  if (!entry_ptr->allow_all_methods &&
      entry_ptr->methods.find(new_request_method) == entry_ptr->methods.end()) {
    return false;
  }
  // Header name is safe if it's not CORS non-wildcard request-header
  // name("Authentication") and last preflight allowed * headers.
  if (entry_ptr->allow_all_headers_except_non_wildcard) {
    bool has_auth_header = false;
    for (auto header : unsafe_headernames) {
      if (SbStringCompareNoCase(header.c_str(), kAuthorization)) {
        has_auth_header = true;
        break;
      }
    }
    // wildcard header is allowed if entry's allowed headers include it.
    return !has_auth_header ||
           (entry_ptr->headernames.find(std::string(kAuthorization)) !=
            entry_ptr->headernames.end());
  }
  // If last preflight does not allow arbitrary header, then match each header
  // with allowed headers.
  for (auto unsafe_headername : unsafe_headernames) {
    if (entry_ptr->headernames.find(unsafe_headername) ==
        entry_ptr->headernames.end()) {
      return false;
    }
  }
  return true;
}

void CORSPreflightCache::ClearObsoleteEntries() {
  while (expiration_time_heap_.size() > 0 &&
         expiration_time_heap_.top().expiration_time < base::Time::Now()) {
    DCHECK(content_.find(expiration_time_heap_.top().url_str) !=
           content_.end());
    auto url_iter = content_.find(expiration_time_heap_.top().url_str);
    DCHECK(url_iter->second.find(expiration_time_heap_.top().origin) !=
           url_iter->second.end());
    auto entry_iter = url_iter->second.find(expiration_time_heap_.top().origin);
    // The entry could have been updated and should only delete obselete ones.
    if (entry_iter->second->expiration_time < base::Time::Now()) {
      url_iter->second.erase(entry_iter);
    }
    expiration_time_heap_.pop();
  }
}

}  // namespace loader
}  // namespace cobalt
