// Copyright 2014 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/dom/html_link_element.h"

#include <algorithm>
#include <memory>
#include <string>
#include <vector>

#include "base/bind.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/string_tokenizer.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "cobalt/cssom/css_parser.h"
#include "cobalt/cssom/css_style_sheet.h"
#include "cobalt/dom/document.h"
#include "cobalt/dom/html_element_context.h"
#include "cobalt/dom/window.h"
#include "cobalt/web/csp_delegate.h"
#include "starboard/common/time.h"
#include "url/gurl.h"

namespace cobalt {
namespace dom {
namespace {

// Constants for parse time histogram. Do not modify these. If you need to
// change these, create a new histogram and new constants.
constexpr size_t kNumParseTimeHistogramBuckets = 100;
constexpr base::TimeDelta kParseTimeHistogramMinTime =
    base::TimeDelta::FromMicroseconds(1);
constexpr base::TimeDelta kParseTimeHistogramMaxTime =
    base::TimeDelta::FromMilliseconds(10);

bool IsValidRelChar(char const& c) {
  return (isalnum(c) || c == '_' || c == '\\' || c == '-');
}

bool IsValidSplashScreenFormat(const std::string& rel) {
  base::StringTokenizer tokenizer(rel, "_");
  tokenizer.set_options(base::StringTokenizer::RETURN_DELIMS);
  bool is_valid_format = true;
  while (tokenizer.GetNext()) {
    std::string token = tokenizer.token();
    if (strcmp(token.c_str(), "splashscreen") == 0) {
      is_valid_format = true;
    } else {
      for (char const& c : token) {
        if (!IsValidRelChar(c)) {
          return false;
        }
      }
      is_valid_format = false;
    }
  }
  return is_valid_format;
}

web::CspDelegate::ResourceType GetCspResourceTypeForRel(
    const std::string& rel) {
  if (rel == "stylesheet") {
    return web::CspDelegate::kStyle;
  } else if (IsValidSplashScreenFormat(rel)) {
    return web::CspDelegate::kLocation;
  } else {
    NOTIMPLEMENTED();
    return web::CspDelegate::kImage;
  }
}

bool IsRelContentCriticalResource(const std::string& rel) {
  return rel == "stylesheet";
}

loader::RequestMode GetRequestMode(
    const base::Optional<std::string>& cross_origin_attribute) {
  // https://html.spec.whatwg.org/#cors-settings-attribute
  if (cross_origin_attribute) {
    if (*cross_origin_attribute == "use-credentials") {
      return loader::kCORSModeIncludeCredentials;
    } else {
      // The invalid value default of crossorigin is Anonymous state, leading to
      // "same-origin" credentials mode.
      return loader::kCORSModeSameOriginCredentials;
    }
  }
  // crossorigin attribute's missing value default is No CORS state, leading to
  // "no-cors" request mode.
  return loader::kNoCORSMode;
}
}  // namespace

// static
const char HTMLLinkElement::kTagName[] = "link";
// static
const std::vector<std::string> HTMLLinkElement::kSupportedRelValues = {
    "stylesheet"};

void HTMLLinkElement::OnInsertedIntoDocument() {
  HTMLElement::OnInsertedIntoDocument();
  if (std::find(kSupportedRelValues.begin(), kSupportedRelValues.end(),
                rel()) != kSupportedRelValues.end()) {
    Obtain();
  } else if (IsValidSplashScreenFormat(rel())) {
    Obtain();
  } else {
    LOG(WARNING) << "<link> has unsupported rel value: " << rel() << ".";
  }
}

base::Optional<std::string> HTMLLinkElement::cross_origin() const {
  base::Optional<std::string> cross_origin_attribute =
      GetAttribute("crossOrigin");
  if (cross_origin_attribute &&
      (*cross_origin_attribute != "anonymous" &&
       *cross_origin_attribute != "use-credentials")) {
    return std::string();
  }
  return cross_origin_attribute;
}

void HTMLLinkElement::set_cross_origin(
    const base::Optional<std::string>& value) {
  if (value) {
    SetAttribute("crossOrigin", *value);
  } else {
    RemoveAttribute("crossOrigin");
  }
}

void HTMLLinkElement::OnRemovedFromDocument() {
  HTMLElement::OnRemovedFromDocument();

  DCHECK(base::MessageLoop::current());
  ReleaseLoader();

  if (style_sheet_) {
    Document* document = node_document();
    if (document) {
      document->OnStyleSheetsModified();
    }
  }
}

void HTMLLinkElement::ResolveAndSetAbsoluteURL() {
  // Resolve the URL given by the href attribute, relative to the element.
  const GURL& base_url = node_document()->location()->url();
  absolute_url_ = base_url.Resolve(href());

  LOG_IF(WARNING, !absolute_url_.is_valid())
      << href() << " cannot be resolved based on " << base_url << ".";
}

// Algorithm for Obtain:
//   https://www.w3.org/TR/html50/document-metadata.html#concept-link-obtain
void HTMLLinkElement::Obtain() {
  TRACE_EVENT0("cobalt::dom", "HTMLLinkElement::Obtain()");
  // Custom, not in any spec.
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  Document* document = node_document();

  // If the document has no browsing context, do not obtain, parse or apply the
  // resource.
  if (!document->html_element_context()) {
    return;
  }

  DCHECK(base::MessageLoop::current());
  DCHECK(!loader_);

  // 1. If the href attribute's value is the empty string, then abort these
  // steps.
  if (href().empty()) {
    return;
  }

  // 2. Resolve the URL given by the href attribute, relative to the element.
  ResolveAndSetAbsoluteURL();

  // 3. If the previous step fails, then abort these steps.
  if (!absolute_url_.is_valid()) {
    return;
  }

  // 4. Do a potentially CORS-enabled fetch of the resulting absolute URL, with
  // the mode being the current state of the element's crossorigin content
  // attribute, the origin being the origin of the link element's Document, and
  // the default origin behaviour set to taint.
  csp::SecurityCallback csp_callback = base::Bind(
      &web::CspDelegate::CanLoad, base::Unretained(document->GetCSPDelegate()),
      GetCspResourceTypeForRel(rel()));

  fetched_last_url_origin_ = loader::Origin();

  if (IsRelContentCriticalResource(rel())) {
    // The element must delay the load event of the element's document until all
    // the attempts to obtain the resource and its critical subresources are
    // complete.
    document->IncreaseLoadingCounter();
  }

  request_mode_ = GetRequestMode(GetAttribute("crossOrigin"));

  DCHECK(!loader_);
  loader::Origin origin = document->location()
                              ? document->location()->GetOriginAsObject()
                              : loader::Origin();
  network::disk_cache::ResourceType type;
  if (rel() == "stylesheet") {
    type = network::disk_cache::kCSS;
  } else if (IsValidSplashScreenFormat(rel())) {
    type = network::disk_cache::kSplashScreen;
  } else {
    LOG(WARNING) << "<link> has unsupported rel value: " << rel() << ".";
    NOTIMPLEMENTED();
    return;
  }

  loader_ = html_element_context()->loader_factory()->CreateLinkLoader(
      absolute_url_, origin, csp_callback, request_mode_, type,
      base::Bind(&HTMLLinkElement::OnContentProduced, base::Unretained(this)),
      base::Bind(&HTMLLinkElement::OnLoadingComplete, base::Unretained(this)));
}

void HTMLLinkElement::OnContentProduced(const loader::Origin& last_url_origin,
                                        std::unique_ptr<std::string> content) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK(content);
  TRACE_EVENT0("cobalt::dom", "HTMLLinkElement::OnContentProduced()");

  // Get resource's final destination url from loader.
  fetched_last_url_origin_ = last_url_origin;

  Document* document = node_document();
  if (rel() == "stylesheet") {
    OnStylesheetLoaded(document, *content);
  } else if (IsValidSplashScreenFormat(rel())) {
    OnSplashscreenLoaded(document, *content);
  } else {
    NOTIMPLEMENTED();
    return;
  }
  // Once the attempts to obtain the resource and its critical subresources
  // are complete, the user agent must, if the loads were successful, queue a
  // task to fire a simple event named load at the link element, or, if the
  // resource or one of its critical subresources failed to completely load
  // for any reason (e.g. DNS error, HTTP 404 response, a connection being
  // prematurely closed, unsupported Content-Type), queue a task to fire a
  // simple event named error at the link element.
  PostToDispatchEventName(FROM_HERE, base::Tokens::load());

  if (IsRelContentCriticalResource(rel())) {
    // The element must delay the load event of the element's document until all
    // the attempts to obtain the resource and its critical subresources are
    // complete.
    document->DecreaseLoadingCounterAndMaybeDispatchLoadEvent();
  }
}

void HTMLLinkElement::OnLoadingComplete(
    const base::Optional<std::string>& error) {
  // GetLoadTimingInfo and create resource timing before loader released.
  GetLoadTimingInfoAndCreateResourceTiming();

  base::ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE, base::Bind(&HTMLLinkElement::ReleaseLoader, this));

  if (!error) return;

  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  TRACE_EVENT0("cobalt::dom", "HTMLLinkElement::OnLoadingComplete()");

  LOG(ERROR) << *error;

  // Once the attempts to obtain the resource and its critical subresources are
  // complete, the user agent must, if the loads were successful, queue a task
  // to fire a simple event named load at the link element, or, if the resource
  // or one of its critical subresources failed to completely load for any
  // reason (e.g. DNS error, HTTP 404 response, a connection being prematurely
  // closed, unsupported Content-Type), queue a task to fire a simple event
  // named error at the link element.
  PostToDispatchEventName(FROM_HERE, base::Tokens::error());

  if (IsRelContentCriticalResource(rel())) {
    // The element must delay the load event of the element's document until all
    // the attempts to obtain the resource and its critical subresources are
    // complete.
    node_document()->DecreaseLoadingCounterAndMaybeDispatchLoadEvent();
  }
}

void HTMLLinkElement::OnSplashscreenLoaded(Document* document,
                                           const std::string& content) {
  scoped_refptr<Window> window = document->window();
  std::string link = rel();
  size_t last_underscore = link.find_last_of("_");
  base::Optional<std::string> topic;
  if (last_underscore != std::string::npos) {
    topic = link.substr(0, last_underscore);
  }
  window->CacheSplashScreen(content, topic);
}

void HTMLLinkElement::OnStylesheetLoaded(Document* document,
                                         const std::string& content) {
  auto before_parse_micros = starboard::CurrentMonotonicTime();
  scoped_refptr<cssom::CSSStyleSheet> css_style_sheet =
      document->html_element_context()->css_parser()->ParseStyleSheet(
          content, base::SourceLocation(href(), 1, 1));
  auto after_parse_micros = starboard::CurrentMonotonicTime();
  auto css_kb = content.length() / 1000;
  // Only measure non-trivial CSS sizes and ignore non-HTTP schemes (e.g.,
  // file://), which are primarily used for debug purposes.
  if (css_kb > 0 && absolute_url_.SchemeIsHTTPOrHTTPS()) {
    // Get parse time normalized by byte size, see:
    // go/cobalt-js-css-parsing-metrics.
    auto micros_per_kb = (after_parse_micros - before_parse_micros) / css_kb;
    UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES(
        "Cobalt.DOM.CSS.Link.ParseTimeMicrosPerKB",
        base::TimeDelta::FromMicroseconds(micros_per_kb),
        kParseTimeHistogramMinTime, kParseTimeHistogramMaxTime,
        kNumParseTimeHistogramBuckets);
  }
  css_style_sheet->SetLocationUrl(absolute_url_);
  // If not loading from network-fetched resources or fetched resource is same
  // origin as the document, set origin-clean flag to true.
  if (request_mode_ != loader::kNoCORSMode || !loader_ ||
      document->location()->url().SchemeIsFile() ||
      (fetched_last_url_origin_ == document->location()->GetOriginAsObject())) {
    css_style_sheet->SetOriginClean(true);
  }
  style_sheet_ = css_style_sheet;
  document->OnStyleSheetsModified();
}

void HTMLLinkElement::ReleaseLoader() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  loader_.reset();
}

void HTMLLinkElement::CollectStyleSheet(
    cssom::StyleSheetVector* style_sheets) const {
  if (style_sheet_) {
    style_sheets->push_back(style_sheet_);
  }
}

void HTMLLinkElement::GetLoadTimingInfoAndCreateResourceTiming() {
  if (html_element_context()->performance() == nullptr) return;
  if (loader_) {
    html_element_context()->performance()->CreatePerformanceResourceTiming(
        loader_->get_load_timing_info(), kTagName, absolute_url_.spec());
  }
}

}  // namespace dom
}  // namespace cobalt
