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

namespace cobalt {
namespace dom {

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.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);
  }
}

}  // namespace dom
}  // namespace cobalt
