/*
 * Copyright 2010 Google Inc.
 *
 * 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.
 */

// Author: gagansingh@google.com (Gagan Singh)

#include "net/instaweb/rewriter/public/js_disable_filter.h"

#include "net/instaweb/http/public/log_record.h"
#include "net/instaweb/rewriter/public/flush_early_content_writer_filter.h"
#include "net/instaweb/rewriter/public/js_defer_disabled_filter.h"
#include "net/instaweb/rewriter/public/rewrite_driver.h"
#include "net/instaweb/rewriter/public/rewrite_options.h"
#include "pagespeed/kernel/base/escaping.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/base/string_util.h"
#include "pagespeed/kernel/html/html_element.h"
#include "pagespeed/kernel/html/html_name.h"
#include "pagespeed/kernel/html/html_node.h"
#include "pagespeed/kernel/http/user_agent_matcher.h"
#include "pagespeed/opt/logging/enums.pb.h"

namespace net_instaweb {

const char JsDisableFilter::kEnableJsExperimental[] =
    "window.pagespeed = window.pagespeed || {};"
    "window.pagespeed.defer_js_experimental=true;";
const char JsDisableFilter::kElementOnloadCode[] =
    "var elem=this;"
    "if (this==window) elem=document.body;"
    "elem.setAttribute('data-pagespeed-loaded', 1)";

JsDisableFilter::JsDisableFilter(RewriteDriver* driver)
    : CommonFilter(driver),
      script_tag_scanner_(driver),
      index_(0),
      ie_meta_tag_written_(false),
      max_prefetch_js_elements_(0) {
}

JsDisableFilter::~JsDisableFilter() {
}

void JsDisableFilter::DetermineEnabled(GoogleString* disabled_reason) {
  bool should_apply = JsDeferDisabledFilter::ShouldApply(driver());
  set_is_enabled(should_apply);
  AbstractLogRecord* log_record = driver()->log_record();
  if (should_apply) {
    log_record->LogRewriterHtmlStatus(
        RewriteOptions::FilterId(RewriteOptions::kDisableJavascript),
        RewriterHtmlApplication::ACTIVE);
  } else if (!driver()->flushing_early()) {
    log_record->LogRewriterHtmlStatus(
        RewriteOptions::FilterId(RewriteOptions::kDisableJavascript),
        RewriterHtmlApplication::USER_AGENT_NOT_SUPPORTED);
  }
}

void JsDisableFilter::StartDocumentImpl() {
  index_ = 0;
  ie_meta_tag_written_ = false;
  should_look_for_prefetch_js_elements_ = false;
  prefetch_js_elements_.clear();
  prefetch_js_elements_count_ = 0;
  max_prefetch_js_elements_ =
      driver()->options()->max_prefetch_js_elements();
  prefetch_mechanism_ =
      driver()->user_agent_matcher()->GetPrefetchMechanism(
          driver()->user_agent());
}

void JsDisableFilter::InsertJsDeferExperimentalScript() {
  bool defer_js_experimental =
      driver()->options()->enable_defer_js_experimental();
  if (!defer_js_experimental) {
    return;
  }
  // We are not adding this code in js_defer_disabled_filter to avoid
  // duplication of code for blink and critical line code.
  HtmlElement* script_node =
      driver()->NewElement(NULL, HtmlName::kScript);

  driver()->AddAttribute(script_node, HtmlName::kType, "text/javascript");
  driver()->AddAttribute(script_node, HtmlName::kDataPagespeedNoDefer, NULL);
  HtmlNode* script_code =
      driver()->NewCharactersNode(script_node, kEnableJsExperimental);
  InsertNodeAtBodyEnd(script_node);
  driver()->AppendChild(script_node, script_code);
}

void JsDisableFilter::InsertMetaTagForIE(HtmlElement* element) {
  if (ie_meta_tag_written_) {
    return;
  }
  ie_meta_tag_written_ = true;
  if (!driver()->user_agent_matcher()->IsIe(driver()->user_agent())) {
    return;
  }

  HtmlElement* head_node = element;
  if (element->keyword() != HtmlName::kHead) {
    head_node =
        driver()->NewElement(element->parent(), HtmlName::kHead);
    driver()->InsertNodeBeforeCurrent(head_node);
  }
  // TODO(ksimbili): Don't add the following if there is already a meta tag
  // and if it's content is greater than IE8 (deferJs supported version).
  HtmlElement* meta_tag =
      driver()->NewElement(head_node, HtmlName::kMeta);

  driver()->AddAttribute(meta_tag, HtmlName::kHttpEquiv, "X-UA-Compatible");
  driver()->AddAttribute(meta_tag, HtmlName::kContent, "IE=edge");
  driver()->PrependChild(head_node, meta_tag);
}

void JsDisableFilter::StartElementImpl(HtmlElement* element) {
  if (element->keyword() == HtmlName::kHead) {
    if (!ie_meta_tag_written_) {
      InsertMetaTagForIE(element);
    }
    should_look_for_prefetch_js_elements_ = true;
  } else if (element->keyword() == HtmlName::kBody) {
    if (!ie_meta_tag_written_) {
      InsertMetaTagForIE(element);
    }
    if (prefetch_js_elements_count_ != 0) {
      // We have collected some script elements that can be downloaded early.
      should_look_for_prefetch_js_elements_ = false;
      // The method to download the scripts differs based on the user agent.
      // Iframe is used for non-chrome UAs whereas for Chrome, the scripts are
      // downloaded as Image.src().
      if (prefetch_mechanism_ == UserAgentMatcher::kPrefetchImageTag) {
        HtmlElement* script = driver()->NewElement(element, HtmlName::kScript);
        driver()->AddAttribute(
            script, HtmlName::kDataPagespeedNoDefer, NULL);
        GoogleString script_data = StrCat("(function(){", prefetch_js_elements_,
                                          "})()");
        driver()->PrependChild(element, script);
        HtmlNode* script_code =
            driver()->NewCharactersNode(script, script_data);
        driver()->AppendChild(script, script_code);
      }
    }
  } else {
    HtmlElement::Attribute* src;
    if (script_tag_scanner_.ParseScriptElement(element, &src) ==
        ScriptTagScanner::kJavaScript) {
      if (element->FindAttribute(HtmlName::kDataPagespeedNoDefer) ||
          element->FindAttribute(HtmlName::kPagespeedNoDefer)) {
        driver()->log_record()->LogJsDisableFilter(
            RewriteOptions::FilterId(RewriteOptions::kDisableJavascript), true);
        return;
      }

      // Honor disallow.
      if (src != NULL && src->DecodedValueOrNull() != NULL) {
        GoogleUrl abs_url(driver()->base_url(), src->DecodedValueOrNull());
        if (abs_url.IsWebValid() &&
            !driver()->options()->IsAllowed(abs_url.Spec())) {
          driver()->log_record()->LogJsDisableFilter(
              RewriteOptions::FilterId(RewriteOptions::kDisableJavascript),
              true);
          return;
        }
      }

      // TODO(rahulbansal): Add a separate bool to track the inline
      // scripts till first external script which aren't deferred.1
      driver()->log_record()->LogJsDisableFilter(
          RewriteOptions::FilterId(RewriteOptions::kDisableJavascript), false);

      // TODO(rahulbansal): Add logging for prioritize scripts
      if (src != NULL) {
        if (should_look_for_prefetch_js_elements_ &&
            prefetch_js_elements_count_ < max_prefetch_js_elements_) {
          GoogleString escaped_source;
          if (prefetch_mechanism_ == UserAgentMatcher::kPrefetchImageTag) {
            EscapeToJsStringLiteral(src->DecodedValueOrNull(), false,
                                    &escaped_source);
            StrAppend(&prefetch_js_elements_, StringPrintf(
                      FlushEarlyContentWriterFilter::kPrefetchImageTagHtml,
                      escaped_source.c_str()));
          }
          prefetch_js_elements_count_++;
        }
      }
      HtmlElement::Attribute* type = element->FindAttribute(HtmlName::kType);
      if (type != NULL) {
        type->set_name(driver()->MakeName(HtmlName::kDataPagespeedOrigType));
      }
      // Delete all type attributes if any. Some sites have more than one type
      // attribute(duplicate). Chrome and firefox picks up the first type
      // attribute for the node.
      while (element->DeleteAttribute(HtmlName::kType)) {}
      HtmlElement::Attribute* prioritize_attr = element->FindAttribute(
          HtmlName::kDataPagespeedPrioritize);
      if (prioritize_attr != NULL &&
          driver()->options()->enable_prioritizing_scripts()) {
        element->AddAttribute(
            driver()->MakeName(HtmlName::kType), "text/prioritypsajs",
            HtmlElement::DOUBLE_QUOTE);
      } else {
        element->AddAttribute(
            driver()->MakeName(HtmlName::kType), "text/psajs",
            HtmlElement::DOUBLE_QUOTE);
      }
      element->AddAttribute(driver()->MakeName(HtmlName::kOrigIndex),
                            IntegerToString(index_++),
                            HtmlElement::DOUBLE_QUOTE);
    }
  }

  HtmlElement::Attribute* onload = element->FindAttribute(HtmlName::kOnload);
  if (onload != NULL) {
    // The onload value can be any script. It's not necessary that it is
    // always javascript. But we don't have any way of identifying it.
    // For now let us assume it is JS, which is the case in majority.
    // TODO(ksimbili): Try fixing not adding non-Js code, if we can.
    // TODO(ksimbili): Call onloads on elements in the same order as they are
    // triggered.
    onload->set_name(driver()->MakeName("data-pagespeed-onload"));
    driver()->AddEscapedAttribute(element, HtmlName::kOnload,
                                  kElementOnloadCode);
    // TODO(sligocki): Should we add onerror handler here too?
  }
}

void JsDisableFilter::EndElementImpl(HtmlElement* element) {
  if (element->keyword() == HtmlName::kHead) {
    should_look_for_prefetch_js_elements_ = false;
  }
}

void JsDisableFilter::EndDocument() {
  InsertJsDeferExperimentalScript();
}

}  // namespace net_instaweb
