// Copyright 2015 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 "cobalt/csp/source.h"

#include "base/logging.h"
#include "base/string_util.h"

namespace cobalt {
namespace csp {

Source::Source(ContentSecurityPolicy* policy, const SourceConfig& config)
    : policy_(policy) {
  // All comparisons require case-insensitivity.
  // Lower-case everything here to simplify that.
  config_.scheme = StringToLowerASCII(config.scheme);
  config_.host = StringToLowerASCII(config.host);
  config_.path = StringToLowerASCII(config.path);
  config_.port = config.port;
  config_.host_wildcard = config.host_wildcard;
  config_.port_wildcard = config.port_wildcard;
}

// https://www.w3.org/TR/2015/CR-CSP2-20150721/#match-source-expression
bool Source::Matches(
    const GURL& url,
    ContentSecurityPolicy::RedirectStatus redirect_status) const {
  if (!SchemeMatches(url)) {
    return false;
  }
  if (IsSchemeOnly()) {
    return true;
  }
  if (!HostMatches(url)) {
    return false;
  }
  if (!PortMatches(url)) {
    return false;
  }

  bool paths_match = (redirect_status == ContentSecurityPolicy::kDidRedirect) ||
                     PathMatches(url);
  return paths_match;
}

bool Source::SchemeMatches(const GURL& url) const {
  if (config_.scheme.empty()) {
    return policy_->SchemeMatchesSelf(url);
  }
  if (LowerCaseEqualsASCII(config_.scheme, "http")) {
    return url.SchemeIs("http") || url.SchemeIs("https");
  }
  if (LowerCaseEqualsASCII(config_.scheme, "ws")) {
    return url.SchemeIs("ws") || url.SchemeIs("wss");
  }
  return url.SchemeIs(config_.scheme.c_str());
}

bool Source::HostMatches(const GURL& url) const {
  const std::string& host = url.host();
  bool match;
  if (config_.host_wildcard == SourceConfig::kHasWildcard) {
    match = EndsWith(host, "." + config_.host, false /* case_sensitive */);
  } else {
    match = LowerCaseEqualsASCII(host, config_.host.c_str());
  }
  return match;
}

bool Source::PathMatches(const GURL& url) const {
  if (config_.path.empty()) {
    return true;
  }

  std::string path = StringToLowerASCII(url.path());
  if (EndsWith(config_.path, "/", true /* case sensitive */)) {
    return StartsWithASCII(path, config_.path, true /* case_sensitive */);
  } else {
    return path == config_.path;
  }
}
// https://www.w3.org/TR/2015/CR-CSP2-20150721/#match-source-expression #9-10
bool Source::PortMatches(const GURL& url) const {
  if (config_.port_wildcard == SourceConfig::kHasWildcard) {
    return true;
  }

  // Matches if ports are the same. If a port is unspecified, consider it as
  // the default port for url's scheme.
  const std::string& url_scheme = url.scheme();
  int config_port = config_.port;
  if (config_port == url_parse::PORT_UNSPECIFIED) {
    config_port = url_canon::DefaultPortForScheme(
        url_scheme.c_str(), static_cast<int>(url_scheme.length()));
  }
  int url_port = url.EffectiveIntPort();
  if (url_port == config_port) {
    return true;
  }

  return false;
}

bool Source::IsSchemeOnly() const { return config_.host.empty(); }

}  // namespace csp
}  // namespace cobalt
