/*
 * 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/http/public/logging_proto_impl.h"
#include "net/instaweb/rewriter/public/rewrite_driver.h"
#include "net/instaweb/rewriter/public/rewrite_options.h"
#include "net/instaweb/rewriter/public/rewrite_test_base.h"
#include "testing/base/public/gunit.h"
#include "pagespeed/kernel/base/scoped_ptr.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/base/string_util.h"
#include "pagespeed/kernel/base/string_writer.h"
#include "pagespeed/kernel/http/user_agent_matcher_test_base.h"
#include "pagespeed/opt/logging/enums.pb.h"

namespace net_instaweb {

namespace {

const char kUnrelatedNoscriptTags[] =
    "<noscript>This is original noscript tag</noscript>";
const char kUnrelatedTags[] =
    "<div id=\"contentContainer\">"
    "<h1>Hello 1</h1>"
    "<div id=\"middleFooter\"><h3>Hello 3</h3></div>"
    "</div>";
const char kXUACompatibleMetaTag[] =
    "<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">";

}  // namespace


class JsDisableFilterTest : public RewriteTestBase {
 protected:
  virtual void SetUp() {
    options_->EnableFilter(RewriteOptions::kDisableJavascript);
    options_->EnableFilter(RewriteOptions::kDeferJavascript);
    options_->Disallow("*donotmove*");
    RewriteTestBase::SetUp();
    filter_.reset(new JsDisableFilter(rewrite_driver()));
    rewrite_driver()->AddFilter(filter_.get());
  }

  virtual bool AddBody() const {
    return false;
  }

  void ExpectLogRecord(int index, int status, bool has_pagespeed_no_defer) {
    AbstractLogRecord* log_record = rewrite_driver_->log_record();
    const RewriterInfo& rewriter_info =
        log_record->logging_info()->rewriter_info(index);
    EXPECT_EQ("jd", rewriter_info.id());
    EXPECT_EQ(status, rewriter_info.status());
    EXPECT_EQ(has_pagespeed_no_defer,
              rewriter_info.rewrite_resource_info().has_pagespeed_no_defer());
  }

  scoped_ptr<JsDisableFilter> filter_;
};

TEST_F(JsDisableFilterTest, DisablesScript) {
  const GoogleString input_html = StrCat(
      "<body>",
      kUnrelatedNoscriptTags,
      "<script></script>"
      "<script src=\"blah1\" random=\"true\">hi1</script>",
      kUnrelatedTags,
      "<img src=\"abc.jpg\" onload=\"foo1('abc');foo2();\">"
      "<script src=\"blah2\" random=\"false\">hi2</script>"
      "<script src=\"blah3\" data-pagespeed-no-defer=\"\"></script>"
      "<script src=\"blah4\" pagespeed_no_defer=\"\"></script>"
      "<script src=\"something-donotmove\"></script>"
      "</body>");
  const GoogleString expected = StrCat(
      "<body>",
      kUnrelatedNoscriptTags,
      "<script type=\"text/psajs\" orig_index=\"0\"></script>"
      "<script src=\"blah1\" random=\"true\" type=\"text/psajs\""
      " orig_index=\"1\">hi1</script>",
      kUnrelatedTags, StrCat(
      "<img src=\"abc.jpg\" data-pagespeed-onload=\"foo1('abc');foo2();\" "
      "onload=\"", JsDisableFilter::kElementOnloadCode, "\">"
      "<script src=\"blah2\" random=\"false\""
      " type=\"text/psajs\" orig_index=\"2\">hi2</script>"
      "<script src=\"blah3\" data-pagespeed-no-defer=\"\"></script>"
      "<script src=\"blah4\" pagespeed_no_defer=\"\"></script>"
      "<script src=\"something-donotmove\"></script>"
      "</body>"));

  ValidateExpectedUrl("http://example.com/", input_html, expected);
  ExpectLogRecord(0, RewriterApplication::APPLIED_OK, false);
  ExpectLogRecord(1, RewriterApplication::APPLIED_OK, false);
  ExpectLogRecord(2, RewriterApplication::APPLIED_OK, false);
  ExpectLogRecord(3, RewriterApplication::APPLIED_OK, true);
  ExpectLogRecord(4, RewriterApplication::APPLIED_OK, true);
  ExpectLogRecord(5, RewriterApplication::APPLIED_OK, true);
  rewrite_driver_->log_record()->WriteLog();
  for (int i = 0; i < logging_info()->rewriter_stats_size(); i++) {
    if (logging_info()->rewriter_stats(i).id() == "jd" &&
        logging_info()->rewriter_stats(i).has_html_status()) {
      EXPECT_EQ(RewriterHtmlApplication::ACTIVE,
                logging_info()->rewriter_stats(i).html_status());
      const RewriteStatusCount& count_applied =
          logging_info()->rewriter_stats(i).status_counts(0);
      EXPECT_EQ(RewriterApplication::APPLIED_OK,
                count_applied.application_status());
      EXPECT_EQ(6, count_applied.count());
      return;
    }
  }
  FAIL();
}

TEST_F(JsDisableFilterTest, InvalidUserAgent) {
  SetCurrentUserAgent("BlackListUserAgent");
  const char script[] = "<head>"
      "<script "
      "src='http://www.google.com/javascript/ajax_apis.js'></script>"
      "<script"
      "> func();</script>"
      "</head><body>Hello, world!</body>";

  ValidateNoChanges("defer_script", script);
  rewrite_driver_->log_record()->WriteLog();
  for (int i = 0; i < logging_info()->rewriter_stats_size(); i++) {
    if (logging_info()->rewriter_stats(i).id() == "jd" &&
        logging_info()->rewriter_stats(i).has_html_status()) {
      EXPECT_EQ(RewriterHtmlApplication::USER_AGENT_NOT_SUPPORTED,
                logging_info()->rewriter_stats(i).html_status());
      return;
    }
  }
  FAIL();
}

TEST_F(JsDisableFilterTest, DisablesScriptWithExperimental) {
  options()->set_enable_defer_js_experimental(true);

  const char kUnrelatedNoscriptTags[] =
      "<noscript>This is original noscript tag</noscript>";
  const char kUnrelatedTags[] =
      "<div id=\"contentContainer\">"
      "<h1>Hello 1</h1>"
      "<div id=\"middleFooter\"><h3>Hello 3</h3></div>"
      "</div>";

  const GoogleString input_html = StrCat(
      "<body>",
      kUnrelatedNoscriptTags,
      "<script src=\"blah1\" random=\"true\">hi1</script>",
      kUnrelatedTags,
      "<script src=\"blah2\" random=\"false\">hi2</script>",
      "</body>");
  const GoogleString expected = StrCat(
      "<body>",
      kUnrelatedNoscriptTags,
      "<script src=\"blah1\" random=\"true\" type=\"text/psajs\""
      " orig_index=\"0\">hi1</script>",
      kUnrelatedTags,
      "<script src=\"blah2\" random=\"false\""
      " type=\"text/psajs\" orig_index=\"1\">hi2</script>"
      "<script type=\"text/javascript\" data-pagespeed-no-defer>",
      JsDisableFilter::kEnableJsExperimental,
      "</script></body>");

  ValidateExpectedUrl("http://example.com/", input_html, expected);
}

TEST_F(JsDisableFilterTest, DisablesScriptWithQueryParam) {
  const GoogleString input_html = StrCat(
      kUnrelatedNoscriptTags,
      "<script src=\"x?a=b&amp;c=d\" random=\"true\">hi1</script>",
      kUnrelatedTags,
      "<script src=\"y?a=b&amp;c=d\" random=\"false\">hi2</script>");
  const GoogleString expected = StrCat(
      kUnrelatedNoscriptTags,
      "<script src=\"x?a=b&amp;c=d\" random=\"true\""
      " type=\"text/psajs\" orig_index=\"0\">hi1</script>",
      kUnrelatedTags,
      "<script src=\"y?a=b&amp;c=d\" random=\"false\""
      " type=\"text/psajs\" orig_index=\"1\">hi2</script>");

  ValidateExpectedUrl("http://example.com/", input_html, expected);
}

TEST_F(JsDisableFilterTest, PrefetchScriptWithImageTemplate) {
  SetCurrentUserAgent(UserAgentMatcherTestBase::kChrome15UserAgent);
  SetDriverRequestHeaders();
  options()->set_max_prefetch_js_elements(3);
  const GoogleString src_url = "//abc.org/m/load.php?debug=false&amp;"
      "lang=en&amp;modules=startup&amp;only=scripts&amp;*";
  // Verify JS escaping works as expected and not HTML escaping.
  const GoogleString escaped_src = "//abc.org/m/load.php?debug=false&lang=en&"
      "modules=startup&only=scripts&*";

  const GoogleString expected = StrCat(
      "<head>"
      "<script type=\"text/psajs\" orig_index=\"0\"></script>"
      "<script src=\"blah1\" random=\"true\" type=\"text/psajs\""
      " orig_index=\"1\">hi1</script>"
      "<script src=\"blah2\" random=\"false\""
      " type=\"text/psajs\" orig_index=\"2\">hi2</script>"
      "<script src=\"blah3\" data-pagespeed-no-defer></script>"
      "<script src=\"", src_url, "\" type=\"text/psajs\""
      " orig_index=\"3\">hi4</script>"
      "<script src=\"blah5\" type=\"text/psajs\""
      " orig_index=\"4\">Not a prefetch candidate</script>"
      "</head><body>"
      "<script data-pagespeed-no-defer>(function(){"
      "new Image().src=\"blah1\";"
      "new Image().src=\"blah2\";"
      "new Image().src=\"", escaped_src, "\";})()"
      "</script></body>");

  html_parse()->SetWriter(&write_to_string_);
  html_parse()->StartParse("http://example.com");
  html_parse()->ParseText(
      "<head>"
      "<script></script>"
      "<script src=\"blah1\" random=\"true\">hi1");
  html_parse()->Flush();
  html_parse()->ParseText(StrCat("</script>"
      "<script src=\"blah2\" random=\"false\">hi2</script>"
      "<script src=\"blah3\" data-pagespeed-no-defer></script>"
      "<script src=\"", src_url, "\">hi4</script>"
      "<script src=\"blah5\">Not a prefetch candidate</script>"
      "</head><body>"));
  html_parse()->Flush();
  html_parse()->ParseText("</body>");
  html_parse()->FinishParse();
  EXPECT_STREQ(expected, output_buffer_);
}

TEST_F(JsDisableFilterTest, PrefetchScriptInHeadNotInBody) {
  SetCurrentUserAgent(UserAgentMatcherTestBase::kChrome15UserAgent);
  options()->set_max_prefetch_js_elements(3);
  const GoogleString input_html = StrCat(
      "<head>",
      kUnrelatedNoscriptTags,
      "<script></script>"
      "<script src=\"blah1\" random=\"true\">hi1</script>",
      kUnrelatedTags,
      "<script src=\"blah2\" random=\"false\">hi2</script>"
      "</head><body>"
      "<script src=\"blah3\" data-pagespeed-no-defer></script>"
      "<script src=\"blah4\">dont show up in prefetch script</script>"
      "</body>");

  const GoogleString prefetch_script =
      "<script data-pagespeed-no-defer>(function(){"
      "new Image().src=\"blah1\";"
      "new Image().src=\"blah2\";})()"
      "</script>";

  const GoogleString expected = StrCat(
      "<head>",
      kUnrelatedNoscriptTags,
      "<script type=\"text/psajs\" orig_index=\"0\"></script>"
      "<script src=\"blah1\" random=\"true\" type=\"text/psajs\""
      " orig_index=\"1\">hi1</script>",
      kUnrelatedTags, StrCat(
      "<script src=\"blah2\" random=\"false\""
      " type=\"text/psajs\" orig_index=\"2\">hi2</script>"
      "</head>"
      "<body>", prefetch_script,
      "<script src=\"blah3\" data-pagespeed-no-defer></script>"
      "<script src=\"blah4\" type=\"text/psajs\""
      " orig_index=\"3\">dont show up in prefetch script</script>"
      "</body>"));

  ValidateExpectedUrl("http://example.com/", input_html, expected);
}

TEST_F(JsDisableFilterTest, DisablesScriptWithUnescapedQueryParam) {
  const GoogleString input_html = StrCat(
      kUnrelatedNoscriptTags,
      "<script src=\"x?a=b&c=d\" random=\"true\">hi1</script>",
      kUnrelatedTags,
      "<script src=\"y?a=b&c=d\" random=\"false\">hi2</script>");
  const GoogleString expected = StrCat(
      kUnrelatedNoscriptTags,
      "<script src=\"x?a=b&c=d\" random=\"true\""
      " type=\"text/psajs\" orig_index=\"0\">hi1</script>",
      kUnrelatedTags,
      "<script src=\"y?a=b&c=d\" random=\"false\""
      " type=\"text/psajs\" orig_index=\"1\">hi2</script>");

  ValidateExpectedUrl("http://example.com/", input_html, expected);
}

TEST_F(JsDisableFilterTest, DisablesScriptWithNullSrc) {
  const GoogleString input_html = StrCat(
      kUnrelatedNoscriptTags,
      "<script src random=\"true\">hi1</script>",
      kUnrelatedTags,
      "<script src random=\"false\">hi2</script>");
  const GoogleString expected = StrCat(
      kUnrelatedNoscriptTags,
      "<script src random=\"true\" type=\"text/psajs\""
      " orig_index=\"0\">hi1</script>",
      kUnrelatedTags,
      "<script src random=\"false\" type=\"text/psajs\""
      " orig_index=\"1\">hi2</script>");

  ValidateExpected("http://example.com/", input_html, expected);
}

TEST_F(JsDisableFilterTest, DisablesScriptOnlyFromFirstSrc) {
  options()->set_enable_defer_js_experimental(true);
  options_->EnableFilter(RewriteOptions::kDeferJavascript);
  const GoogleString input_html = StrCat(
      "<body>",
      kUnrelatedNoscriptTags,
      "<script random=\"true\">hi1</script>",
      kUnrelatedTags,
      "<script random=\"false\">hi2</script>"
      "<script src=\"1.js?a#12296;=en\"></script></body>");
  const GoogleString expected = StrCat(
      "<body>",
      kUnrelatedNoscriptTags,
      "<script random=\"true\" type=\"text/psajs\" orig_index=\"0\">"
      "hi1</script>",
      kUnrelatedTags,
      "<script random=\"false\" type=\"text/psajs\" orig_index=\"1\">"
      "hi2</script>"
      "<script src=\"1.js?a#12296;=en\" type=\"text/psajs\""
      " orig_index=\"2\"></script>"
      "<script type=\"text/javascript\" data-pagespeed-no-defer>",
      JsDisableFilter::kEnableJsExperimental,
      "</script></body>");

  ValidateExpected("http://example.com/", input_html, expected);
}

TEST_F(JsDisableFilterTest, AddsMetaTagForIE) {
  SetCurrentUserAgent("Mozilla/5.0 ( MSIE 10.0; Trident/5.0)");
  const GoogleString input_html = StrCat(
      "<body>",
      kUnrelatedNoscriptTags,
      "<script src=\"blah1\" random=\"true\">hi1</script>",
      kUnrelatedTags,
      "</body>");
  const GoogleString expected = StrCat(
      StrCat("<head>",
      kXUACompatibleMetaTag,
      "</head>"
      "<body>"),
      StrCat(kUnrelatedNoscriptTags,
      "<script src=\"blah1\" random=\"true\" type=\"text/psajs\""
      " orig_index=\"0\">hi1</script>",
      kUnrelatedTags),
      "</body>");

  ValidateExpectedUrl("http://example.com/", input_html, expected);
}

TEST_F(JsDisableFilterTest, DisablesScriptWithMultipleTypeAttributes) {
  const GoogleString input_html = StrCat(
      kUnrelatedNoscriptTags,
      "<script src=\"x?a=b&amp;c=d\" type='text/javascript' type='a' type='b'>"
      "hi1</script>",
      kUnrelatedTags);
  const GoogleString expected = StrCat(
      kUnrelatedNoscriptTags,
      "<script src=\"x?a=b&amp;c=d\""
      " data-pagespeed-orig-type='text/javascript'"
      " type=\"text/psajs\" orig_index=\"0\">hi1</script>",
      kUnrelatedTags);

  ValidateExpectedUrl("http://example.com/", input_html, expected);
}

TEST_F(JsDisableFilterTest, ScriptWithPagespeedPrioritizeAttribute) {
  options()->set_enable_prioritizing_scripts(true);
  const GoogleString input_html = StrCat(
      "<body>",
      kUnrelatedNoscriptTags,
      "<script src=\"blah1\" random=\"true\">hi1</script>",
      kUnrelatedTags,
      "<img src=\"abc.jpg\" onload=\"foo1();foo2();\">"
      "<script src=\"blah2\" random=\"false\" data-pagespeed-prioritize>hi2"
      "</script>"
      "<script data-pagespeed-prioritize>hi5</script>"
      "</body>");
  const GoogleString expected = StrCat(
      "<body>",
      kUnrelatedNoscriptTags,
      "<script src=\"blah1\" random=\"true\" type=\"text/psajs\""
      " orig_index=\"0\">hi1</script>",
      kUnrelatedTags, StrCat(
      "<img src=\"abc.jpg\" data-pagespeed-onload=\"foo1();foo2();\" "
      "onload=\"", JsDisableFilter::kElementOnloadCode, "\">"
      "<script src=\"blah2\" random=\"false\" data-pagespeed-prioritize "
      "type=\"text/prioritypsajs\" orig_index=\"1\">"
      "hi2</script>"
      "<script data-pagespeed-prioritize type=\"text/prioritypsajs\" "
      "orig_index=\"2\">hi5</script>"
      "</body>"));
  ValidateExpectedUrl("http://example.com/", input_html, expected);
}

}  // namespace net_instaweb
