// Copyright 2015 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.

#include "cobalt/network/network_delegate.h"

#include "cobalt/network/local_network.h"
#include "cobalt/network/socket_address_parser.h"
#include "net/base/net_errors.h"
#include "net/base/url_util.h"

namespace cobalt {
namespace network {

NetworkDelegate::NetworkDelegate(net::StaticCookiePolicy::Type cookie_policy,
                                 network::HTTPSRequirement https_requirement)
    : cookie_policy_(cookie_policy),
      cookies_enabled_(true),
      https_requirement_(https_requirement) {}

NetworkDelegate::~NetworkDelegate() {}

int NetworkDelegate::OnBeforeURLRequest(
    net::URLRequest* request, net::CompletionOnceCallback /*callback*/,
    GURL* /*new_url*/) {
  const GURL& url = request->url();
  if (url.SchemeIsCryptographic() || url.SchemeIsFileSystem() ||
      url.SchemeIs("data")) {
    return net::OK;
  } else if (https_requirement_ == kHTTPSOptional) {
    DLOG(WARNING)
        << "Page must be served over secure scheme, it will fail to load "
           "in production builds of Cobalt.";
    return net::OK;
  }

  if (!url.is_valid() || url.is_empty()) {
    return net::ERR_INVALID_ARGUMENT;
  }

  const url::Parsed& parsed = url.parsed_for_possibly_invalid_spec();

  if (!url.has_host() || !parsed.host.is_valid() ||
      !parsed.host.is_nonempty()) {
    return net::ERR_INVALID_ARGUMENT;
  }

  const std::string& valid_spec = url.possibly_invalid_spec();
  const char* valid_spec_cstr = valid_spec.c_str();

  std::string host;
  // This will be our host string if we are not using IPV6.
  host.append(valid_spec_cstr + parsed.host.begin,
              valid_spec_cstr + parsed.host.begin + parsed.host.len);
#if SB_API_VERSION >= SB_IPV6_REQUIRED_VERSION || SB_HAS(IPV6)
#if SB_API_VERSION >= SB_IPV6_REQUIRED_VERSION
  if (SbSocketIsIpv6Supported())
#endif
    host = url.HostNoBrackets();
#endif
  if (net::HostStringIsLocalhost(host)) {
    return net::OK;
  }

  SbSocketAddress destination;
  // Note that ParseSocketAddress will only pass if host is a numeric IP.
  if (!cobalt::network::ParseSocketAddress(valid_spec_cstr, parsed.host,
                                           &destination)) {
    return net::ERR_INVALID_ARGUMENT;
  }

  if (IsIPInPrivateRange(destination) || IsIPInLocalNetwork(destination)) {
    return net::OK;
  }

  return net::ERR_DISALLOWED_URL_SCHEME;
}

int NetworkDelegate::OnBeforeStartTransaction(
    net::URLRequest* /*request*/, net::CompletionOnceCallback /*callback*/,
    net::HttpRequestHeaders* /*headers*/) {
  return net::OK;
}

void NetworkDelegate::OnBeforeSendHeaders(
    net::URLRequest* /*request*/, const net::ProxyInfo& /*proxy_info*/,
    const net::ProxyRetryInfoMap& /*proxy_retry_info*/,
    net::HttpRequestHeaders* /*headers*/) {}

void NetworkDelegate::OnStartTransaction(
    net::URLRequest* /*request*/, const net::HttpRequestHeaders& /*headers*/) {}

int NetworkDelegate::OnHeadersReceived(
    net::URLRequest* /*request*/, net::CompletionOnceCallback /*callback*/,
    const net::HttpResponseHeaders* /*original_response_headers*/,
    scoped_refptr<net::HttpResponseHeaders>* /*override_response_headers*/,
    GURL* /*allowed_unsafe_redirect_url*/) {
  return net::OK;
}

void NetworkDelegate::OnBeforeRedirect(net::URLRequest* /*request*/,
                                       const GURL& /*new_location*/) {}

void NetworkDelegate::OnResponseStarted(net::URLRequest* /*request*/,
                                        int /*net_error*/) {}

void NetworkDelegate::OnNetworkBytesReceived(net::URLRequest* /*request*/,
                                             int64_t /*bytes_received*/) {}

void NetworkDelegate::OnNetworkBytesSent(net::URLRequest* /*request*/,
                                         int64_t /*bytes_sent*/) {}

void NetworkDelegate::OnCompleted(net::URLRequest* /*request*/,
                                  bool /*started*/, int /*net_error*/) {}

void NetworkDelegate::OnURLRequestDestroyed(net::URLRequest* /*request*/) {}

void NetworkDelegate::OnPACScriptError(int /*line_number*/,
                                       const base::string16& /*error*/) {}

net::NetworkDelegate::AuthRequiredResponse NetworkDelegate::OnAuthRequired(
    net::URLRequest* /*request*/, const net::AuthChallengeInfo& /*auth_info*/,
    AuthCallback /*callback*/, net::AuthCredentials* /*credentials*/) {
  return AUTH_REQUIRED_RESPONSE_NO_ACTION;
}

bool NetworkDelegate::OnCanGetCookies(const net::URLRequest& request,
                                      const net::CookieList& /*cookie_list*/,
                                      bool allowed_from_caller) {
  if (!allowed_from_caller) {
    return false;
  }
  net::StaticCookiePolicy policy(ComputeCookiePolicy());
  int rv = policy.CanAccessCookies(request.url(), request.site_for_cookies());
  return rv == net::OK;
}

bool NetworkDelegate::OnCanSetCookie(const net::URLRequest& request,
                                     const net::CanonicalCookie& /*cookie*/,
                                     net::CookieOptions* /*options*/,
                                     bool allowed_from_caller) {
  if (!allowed_from_caller) {
    return false;
  }
  net::StaticCookiePolicy policy(ComputeCookiePolicy());
  int rv = policy.CanAccessCookies(request.url(), request.site_for_cookies());
  return rv == net::OK;
}

bool NetworkDelegate::OnCanAccessFile(
    const net::URLRequest& /*request*/, const base::FilePath& /*original_path*/,
    const base::FilePath& /*absolute_path*/) const {
  return true;
}

bool NetworkDelegate::OnCanEnablePrivacyMode(
    const GURL& /*url*/, const GURL& /*site_for_cookies*/) const {
  return false;
}

bool NetworkDelegate::OnAreExperimentalCookieFeaturesEnabled() const {
  return false;
}

bool NetworkDelegate::OnCancelURLRequestWithPolicyViolatingReferrerHeader(
    const net::URLRequest& /*request*/, const GURL& /*target_url*/,
    const GURL& /*referrer_url*/) const {
  return true;
}

bool NetworkDelegate::OnCanQueueReportingReport(
    const url::Origin& /*origin*/) const {
  return true;
}

void NetworkDelegate::OnCanSendReportingReports(
    std::set<url::Origin> origins,
    base::OnceCallback<void(std::set<url::Origin>)> result_callback) const {
  std::move(result_callback).Run(std::move(origins));
}

bool NetworkDelegate::OnCanSetReportingClient(const url::Origin& /*origin*/,
                                              const GURL& /*endpoint*/) const {
  return true;
}

bool NetworkDelegate::OnCanUseReportingClient(const url::Origin& /*origin*/,
                                              const GURL& /*endpoint*/) const {
  return true;
}

net::StaticCookiePolicy::Type NetworkDelegate::ComputeCookiePolicy() const {
  if (cookies_enabled_) {
    return cookie_policy_;
  } else {
    return net::StaticCookiePolicy::BLOCK_ALL_COOKIES;
  }
}
}  // namespace network
}  // namespace cobalt
