// Copyright 2016 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/web/url_utils.h"

#include <string>

#include "cobalt/loader/origin.h"
#include "url/gurl.h"

namespace cobalt {
namespace web {

std::string URLUtils::href() const { return url_.possibly_invalid_spec(); }

void URLUtils::set_href(const std::string& href) {
  GURL new_url = GURL(href);
  RunPreUpdateSteps(new_url, href);
}

std::string URLUtils::protocol() const { return url_.scheme() + ":"; }

void URLUtils::set_protocol(const std::string& protocol) {
  GURL::Replacements replacements;
  replacements.SetSchemeStr(protocol);
  GURL new_url = url_.ReplaceComponents(replacements);
  RunPreUpdateSteps(new_url, "");
}

std::string URLUtils::host() const {
  return url_.host() + (url_.has_port() ? ":" + url_.port() : "");
}

void URLUtils::set_host(const std::string& host) {
  // Host may include an optional port.
  std::string host_without_port = host;
  std::string port;
  size_t colon_pos = host.find(':');
  if (colon_pos != std::string::npos) {
    host_without_port = host.substr(0, colon_pos);
    port = host.substr(colon_pos + 1);
  }

  GURL::Replacements replacements;
  replacements.SetHostStr(host_without_port);
  if (port.length() > 0) {
    replacements.SetPortStr(port);
  }
  GURL new_url = url_.ReplaceComponents(replacements);
  RunPreUpdateSteps(new_url, "");
}

std::string URLUtils::hostname() const { return url_.host(); }

void URLUtils::set_hostname(const std::string& hostname) {
  GURL::Replacements replacements;
  replacements.SetHostStr(hostname);
  GURL new_url = url_.ReplaceComponents(replacements);
  RunPreUpdateSteps(new_url, "");
}

std::string URLUtils::port() const { return url_.port(); }

void URLUtils::set_port(const std::string& port) {
  GURL::Replacements replacements;
  replacements.SetPortStr(port);
  GURL new_url = url_.ReplaceComponents(replacements);
  RunPreUpdateSteps(new_url, "");
}

std::string URLUtils::pathname() const { return url_.path(); }

void URLUtils::set_pathname(const std::string& pathname) {
  GURL::Replacements replacements;
  replacements.SetPathStr(pathname);
  GURL new_url = url_.ReplaceComponents(replacements);
  RunPreUpdateSteps(new_url, "");
}

std::string URLUtils::hash() const {
  return url_.has_ref() ? "#" + url_.ref() : "";
}

// Algorithm for set_hash:
//   https://www.w3.org/TR/2014/WD-url-1-20141209/#dom-urlutils-hash
void URLUtils::set_hash(const std::string& hash) {
  // 3. Let input be the given value with a single leading "#" removed, if any.
  std::string hash_value =
      !hash.empty() && hash[0] == '#' ? hash.substr(1) : hash;

  GURL::Replacements replacements;
  replacements.SetRefStr(hash_value);
  GURL new_url = url_.ReplaceComponents(replacements);
  RunPreUpdateSteps(new_url, "");
}

std::string URLUtils::search() const {
  return url_.has_query() ? "?" + url_.query() : "";
}

// Algorithm for set_search:
//   https://www.w3.org/TR/2014/WD-url-1-20141209/#dom-urlutils-search
void URLUtils::set_search(const std::string& search) {
  // 3. Let input be the given value with a single leading "?" removed, if any.
  std::string search_value =
      !search.empty() && search[0] == '?' ? search.substr(1) : search;

  GURL::Replacements replacements;
  replacements.SetQueryStr(search_value);
  GURL new_url = url_.ReplaceComponents(replacements);
  RunPreUpdateSteps(new_url, "");
}

// Algorithm for RunPreUpdateSteps:
//   https://www.w3.org/TR/2014/WD-url-1-20141209/#pre-update-steps
void URLUtils::RunPreUpdateSteps(const GURL& new_url,
                                 const std::string& value) {
  DLOG(INFO) << "Update URL to " << new_url.possibly_invalid_spec();

  // 1. If value is not given, let value be the result of serializing the
  // associated url.
  // 2, Run the update steps with value.
  if (update_steps_.is_null()) {
    url_ = new_url;
  } else {
    update_steps_.Run(value.empty() ? new_url.possibly_invalid_spec() : value);
  }
}

std::string URLUtils::origin() const {
  return GetOriginAsObject().SerializedOrigin();
}

loader::Origin URLUtils::GetOriginAsObject() const {
  return loader::Origin(url_);
}

}  // namespace web
}  // namespace cobalt
