/*
 * Copyright 2013 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: morlovich@google.com (Maksim Orlovich)

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

#include "net/instaweb/http/public/log_record.h"
#include "net/instaweb/http/public/logging_proto_impl.h"
#include "net/instaweb/http/public/request_context.h"
#include "net/instaweb/rewriter/flush_early.pb.h"
#include "net/instaweb/rewriter/public/critical_finder_support_util.h"
#include "net/instaweb/rewriter/public/critical_selector_finder.h"
#include "net/instaweb/rewriter/public/css_summarizer_base.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 "net/instaweb/rewriter/public/server_context.h"
#include "net/instaweb/rewriter/public/static_asset_manager.h"
#include "net/instaweb/rewriter/public/test_rewrite_driver_factory.h"
#include "net/instaweb/util/public/mock_property_page.h"
#include "net/instaweb/util/public/property_cache.h"
#include "pagespeed/kernel/base/gtest.h"
#include "pagespeed/kernel/base/hasher.h"
#include "pagespeed/kernel/base/mock_timer.h"
#include "pagespeed/kernel/base/statistics.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/base/string_util.h"
#include "pagespeed/kernel/base/timer.h"
#include "pagespeed/kernel/http/content_type.h"
#include "pagespeed/kernel/http/semantic_type.h"
#include "pagespeed/kernel/http/user_agent_matcher_test_base.h"
#include "pagespeed/opt/logging/enums.pb.h"

namespace net_instaweb {

namespace {

const char kRequestUrl[] = "http://www.example.com/";

class CriticalSelectorFilterTest : public RewriteTestBase {
 protected:
  virtual void SetUpBeforeSelectorsFilter() {
    rewrite_driver()->AddFilters();
  }

  virtual void SetUpAfterSelectorsFilter() {
    server_context()->ComputeSignature(options());
  }

  virtual void SetUp() {
    RewriteTestBase::SetUp();

    // Disable flush early for tests (unless they turn it on).
    options()->set_enable_flush_early_critical_css(false);

    // Enable critical selector filter alone so that
    // testing isn't disrupted by beacon injection.
    SetUpBeforeSelectorsFilter();
    filter_ = new CriticalSelectorFilter(rewrite_driver());
    rewrite_driver()->AppendOwnedPreRenderFilter(filter_);
    SetUpAfterSelectorsFilter();
    // Setup pcache.
    pcache_ = rewrite_driver()->server_context()->page_property_cache();
    const PropertyCache::Cohort* beacon_cohort =
        SetupCohort(pcache_, RewriteDriver::kBeaconCohort);
    const PropertyCache::Cohort* dom_cohort =
        SetupCohort(pcache_, RewriteDriver::kDomCohort);
    server_context()->set_dom_cohort(dom_cohort);
    server_context()->set_beacon_cohort(beacon_cohort);
    server_context()->set_critical_selector_finder(
        new BeaconCriticalSelectorFinder(server_context()->beacon_cohort(),
                                         factory()->nonce_generator(),
                                         statistics()));
    ResetDriver();
    // Set up initial candidates for critical selector beacon
    candidates_.insert("div");
    candidates_.insert("*");
    candidates_.insert("span");
    // Write out some initial critical selectors for us to work with.
    StringSet selectors;
    selectors.insert("div");
    selectors.insert("*");
    WriteCriticalSelectorsToPropertyCache(selectors);

    // Some weird but valid CSS.
    SetResponseWithDefaultHeaders("a.css", kContentTypeCss,
                                  "div,span,*::first-letter { display: block; }"
                                  "p { display: inline; }", 100);
    SetResponseWithDefaultHeaders("b.css", kContentTypeCss,
                                  "@media screen,print { * { margin: 0px; } }",
                                  100);
    SetResponseWithDefaultHeaders("http://unauthorized.com/unauth.css",
                                  kContentTypeCss,
                                  "div { background-color: blue }"
                                  "random { color: white }", 100);
  }

  void ResetDriver() {
    rewrite_driver()->Clear();
    rewrite_driver()->set_request_context(
        RequestContext::NewTestRequestContext(factory()->thread_system()));
    page_ = NewMockPage(kRequestUrl);
    rewrite_driver()->set_property_page(page_);
    pcache_->Read(page_);
    SetHtmlMimetype();  // Don't wrap scripts in <![CDATA[ ]]>
  }

  void WriteCriticalSelectorsToPropertyCache(const StringSet& selectors) {
    factory()->mock_timer()->AdvanceMs(
        options()->beacon_reinstrument_time_sec() * Timer::kSecondMs);
    last_beacon_metadata_ =
        server_context()->critical_selector_finder()->
            PrepareForBeaconInsertion(candidates_, rewrite_driver());
    ASSERT_EQ(kBeaconWithNonce, last_beacon_metadata_.status);
    ResetDriver();
    server_context()->critical_selector_finder()->
        WriteCriticalSelectorsToPropertyCache(
            selectors, last_beacon_metadata_.nonce, rewrite_driver());
    page_->WriteCohort(server_context()->beacon_cohort());
  }

  GoogleString WrapForJsLoad(StringPiece orig_css) {
    return StrCat("<noscript class=\"psa_add_styles\">", orig_css,
                  "</noscript>");
  }

  GoogleString JsLoader() {
    return StrCat(
        "<script data-pagespeed-no-defer type=\"text/javascript\">",
        rewrite_driver()->server_context()->static_asset_manager()->GetAsset(
            StaticAssetEnum::CRITICAL_CSS_LOADER_JS,
            rewrite_driver()->options()),
        "pagespeed.CriticalCssLoader.Run();</script>");
  }

  GoogleString LoadRestOfCss(StringPiece orig_css) {
    return StrCat(WrapForJsLoad(orig_css), JsLoader());
  }

  GoogleString CssLinkHrefMedia(StringPiece url, StringPiece media) {
    return StrCat("<link rel=stylesheet href=", url,
                  " media=\"", media, "\">");
  }

  virtual bool AddHtmlTags() const { return false; }

  void ValidateRewriterLogging(RewriterHtmlApplication::Status html_status) {
    rewrite_driver()->log_record()->WriteLog();

    const LoggingInfo& logging_info =
        *rewrite_driver()->log_record()->logging_info();
    ASSERT_EQ(1, logging_info.rewriter_stats_size());
    const RewriterStats& rewriter_stats = logging_info.rewriter_stats(0);
    EXPECT_EQ("pr", rewriter_stats.id());
    EXPECT_EQ(html_status, rewriter_stats.html_status());
  }

  CriticalSelectorFilter* filter_;  // owned by the driver;
  PropertyCache* pcache_;
  PropertyPage* page_;
  StringSet candidates_;
  BeaconMetadata last_beacon_metadata_;
};

TEST_F(CriticalSelectorFilterTest, BasicOperation) {
  GoogleString css = StrCat(
      "<style>*,p {display: none; } span {display: inline; }</style>",
      CssLinkHref("a.css"),
      CssLinkHref("b.css"));

  GoogleString critical_css =
      "<style>*{display:none}</style>"  // from the inline
      "<style>div,*::first-letter{display:block}</style>"  // from a.css
      "<style>@media screen{*{margin:0}}</style>";  // from b.css

  GoogleString html = StrCat(
      "<head>",
      css,
      "</head>"
      "<body><div>Stuff</div></body>");

  ValidateExpected(
      "basic", html,
      StrCat("<head>", critical_css, "</head>",
             "<body><div>Stuff</div>",
             LoadRestOfCss(css), "</body>"));
  ValidateRewriterLogging(RewriterHtmlApplication::ACTIVE);
}

TEST_F(CriticalSelectorFilterTest, UnauthorizedCss) {
  GoogleString css = StrCat(
      "<style>*,p {display: none; } span {display: inline; }</style>",
      CssLinkHref("http://unauthorized.com/unauth.css"),
      CssLinkHref("a.css"),
      CssLinkHref("b.css"));

  GoogleString critical_css =
      "<style>*{display:none}</style>"  // from the inline
      "<link rel=stylesheet href=http://unauthorized.com/unauth.css>"
      "<style>div,*::first-letter{display:block}</style>"  // from a.css
      "<style>@media screen{*{margin:0}}</style>";  // from b.css

  GoogleString html = StrCat(
      "<head>",
      css,
      "</head>"
      "<body><div>Stuff</div></body>");

  ValidateExpected(
      "basic", html,
      StrCat("<head>", critical_css, "</head>",
             "<body><div>Stuff</div>",
             LoadRestOfCss(css), "</body>"));
  ValidateRewriterLogging(RewriterHtmlApplication::ACTIVE);
  EXPECT_EQ(3, statistics()->GetVariable(
      CssSummarizerBase::kNumCssUsedForCriticalCssComputation)->Get());
  EXPECT_EQ(1, statistics()->GetVariable(
      CssSummarizerBase::kNumCssNotUsedForCriticalCssComputation)->Get());
}

TEST_F(CriticalSelectorFilterTest, AllowUnauthorizedCss) {
  options()->ClearSignatureForTesting();
  options()->AddInlineUnauthorizedResourceType(semantic_type::kStylesheet);
  options()->ComputeSignature();
  GoogleString css = StrCat(
      "<style>*,p {display: none; } span {display: inline; }</style>",
      CssLinkHref("http://unauthorized.com/unauth.css"),
      CssLinkHref("a.css"),
      CssLinkHref("b.css"));

  GoogleString critical_css =
      "<style>*{display:none}</style>"  // from the inline
      "<style>div{background-color:#00f}</style>"  // from unauth.css
      "<style>div,*::first-letter{display:block}</style>"  // from a.css
      "<style>@media screen{*{margin:0}}</style>";  // from b.css

  GoogleString html = StrCat(
      "<head>",
      css,
      "</head>"
      "<body><div>Stuff</div></body>");

  ValidateExpected(
      "basic", html,
      StrCat("<head>", critical_css, "</head>",
             "<body><div>Stuff</div>",
             LoadRestOfCss(css), "</body>"));
  ValidateRewriterLogging(RewriterHtmlApplication::ACTIVE);
  EXPECT_EQ(4, statistics()->GetVariable(
      CssSummarizerBase::kNumCssUsedForCriticalCssComputation)->Get());
  EXPECT_EQ(0, statistics()->GetVariable(
      CssSummarizerBase::kNumCssNotUsedForCriticalCssComputation)->Get());
}

TEST_F(CriticalSelectorFilterTest, StylesInBody) {
  GoogleString css_a = StrCat(
      "<style>*,p {display: none; } span {display: inline; }</style>",
      CssLinkHref("a.css"));
  GoogleString css_b = CssLinkHref("b.css");

  GoogleString critical_css_a =
      "<style>*{display:none}</style>"  // from the inline
      "<style>div,*::first-letter{display:block}</style>";  // from a.css
  GoogleString critical_css_b =
      "<style>@media screen{*{margin:0}}</style>";  // from b.css

  GoogleString html = StrCat(
      "<head></head><body>", css_a,
      "<div>Stuff</div>", css_b,
      "</body>");

  ValidateExpected(
      "style_in_body", html,
      StrCat("<head></head><body>", critical_css_a,
             "<div>Stuff</div>", critical_css_b,
             LoadRestOfCss(css_a + css_b), "</body>"));
  ValidateRewriterLogging(RewriterHtmlApplication::ACTIVE);
}

TEST_F(CriticalSelectorFilterTest, EmptyBlock) {
  // Do not insert empty <style> blocks. Our critical selector sets do not
  // talk about 'i' so this should do nothing..
  GoogleString css = "<style>i { font-style:italic; }</style>";

  GoogleString html = StrCat(
      "<head>",
      css,
      "</head>"
      "<body><div>Stuff</div></body>");

  ValidateExpected(
      "empty_block", html,
      StrCat("<head></head>"
             "<body><div>Stuff</div>",
             LoadRestOfCss(css), "</body>"));
  ValidateRewriterLogging(RewriterHtmlApplication::ACTIVE);
}

TEST_F(CriticalSelectorFilterTest, DisabledForIE) {
  SetCurrentUserAgent(UserAgentMatcherTestBase::kIe7UserAgent);
  GoogleString css = StrCat(
      "<style>*,p {display: none; } span {display: inline; }</style>",
      CssLinkHref("a.css"),
      CssLinkHref("b.css"));
  GoogleString html = StrCat(
      "<head>",
      css,
      "</head>"
      "<body><div>Stuff</div></body>");
  ValidateNoChanges("on_ie", html);
  ValidateRewriterLogging(RewriterHtmlApplication::USER_AGENT_NOT_SUPPORTED);
}

TEST_F(CriticalSelectorFilterTest, NoScript) {
  GoogleString css1 =
      "<style>*,p {display: none; } span {display: inline; }</style>";
  GoogleString css2 =
      StrCat("<noscript>", CssLinkHref("a.css"), "</noscript>");
  GoogleString css3 =
      CssLinkHref("b.css");
  GoogleString css = StrCat(css1, css2, css3);

  GoogleString critical_css =
      "<style>*{display:none}</style>"  // from the inline
      "<noscript></noscript>"  // from a.css
      "<style>@media screen{*{margin:0}}</style>";  // from b.css

  GoogleString html = StrCat(
      "<head>",
      css,
      "</head>"
      "<body><div>Stuff</div></body>");

  ValidateExpected(
      "noscript", html,
      StrCat("<head>", critical_css, "</head>"
             "<body><div>Stuff</div>",
             WrapForJsLoad(css1),
             css2,  // noscript, so not marked for JS load.
             WrapForJsLoad(css3),
             JsLoader(), "</body>"));
  ValidateRewriterLogging(RewriterHtmlApplication::ACTIVE);
}

TEST_F(CriticalSelectorFilterTest, Alternate) {
  GoogleString css = StrCat(
    "<link rel=\"alternate stylesheet\" href=\"a.css\">",
    CssLinkHref("b.css"));

  GoogleString critical_css =
    "<style>@media screen{*{margin:0}}</style>";  // from b.css

  GoogleString html = StrCat(
      "<head>",
      css,
      "</head>"
      "<body><div>Stuff</div></body>");

  ValidateExpected(
      "alternate", html,
      StrCat("<head>", critical_css, "</head>"
             "<body><div>Stuff</div>",
             LoadRestOfCss(css), "</body>"));
}

TEST_F(CriticalSelectorFilterTest, Media) {
  GoogleString css = StrCat(
      "<style media=screen,print>*,p {display: none; } "
          "span {display: inline; }</style>",
      CssLinkHrefMedia("a.css", "screen"),
      CssLinkHrefMedia("b.css", "screen and (color), aural"));

  GoogleString critical_css =
      "<style media=\"screen\">"
          "*{display:none}"  // from the inline
      "</style>"
      "<style media=\"screen\">"
          "div,*::first-letter{display:block}"  // from a.css
      "</style>"
      "<style media=\"screen and (color)\">"
          "@media screen{*{margin:0}}"  // from b.css
      "</style>";

  GoogleString html = StrCat(
      "<head>",
      css,
      "</head>"
      "<body><div>Stuff</div></body>");

  ValidateExpected(
      "foo", html,
      StrCat("<head>", critical_css, "</head>",
             "<body><div>Stuff</div>",
             LoadRestOfCss(css), "</body>"));
}

TEST_F(CriticalSelectorFilterTest, NonScreenMedia) {
  GoogleString css = StrCat(
      "<style media=print>*,p {display: none; } "
          "span {display: inline; }</style>",
      CssLinkHrefMedia("a.css", "screen"),
      CssLinkHrefMedia("b.css", "screen and (color), aural"));

  GoogleString critical_css =
      "<style media=\"screen\">"
          "div,*::first-letter{display:block}"  // from a.css
      "</style>"
      "<style media=\"screen and (color)\">"
          "@media screen{*{margin:0}}"  // from b.css
      "</style>";

  GoogleString html = StrCat(
      "<head>",
      css,
      "</head>"
      "<body><div>Stuff</div></body>");

  ValidateExpected(
      "non_screen_media", html,
      StrCat("<head>", critical_css, "</head>",
             "<body><div>Stuff</div>",
             LoadRestOfCss(css), "</body>"));
}

TEST_F(CriticalSelectorFilterTest, SameCssDifferentSelectors) {
  // We should not reuse results for same CSS when selectors are different.
  GoogleString css = "<style>div,span { display: inline-block; }</style>";

  GoogleString critical_css_div = "div{display:inline-block}";
  GoogleString critical_css_span = "span{display:inline-block}";
  GoogleString critical_css_div_span = "div,span{display:inline-block}";
  // Check what we compute for a page with div.
  ValidateExpected("with_div", StrCat(css, "<div>Foo</div>"),
                   StrCat("<style>", critical_css_div, "</style>",
                          "<div>Foo</div>", LoadRestOfCss(css)));

  // Update the selector list with span. Because we are storing the last N
  // beacon entries, both div and span should now be in the critical set. We
  // also clear the property cache entry for our result, which is needed because
  // the test harness is not really keying the pcache by the URL like the real
  // system would.
  StringSet selectors;
  selectors.insert("span");
  WriteCriticalSelectorsToPropertyCache(selectors);

  // Note that calling ResetDriver() just resets the state in the
  // driver. Whatever has been written to the property & metadata caches so far
  // will persist. Upon rewriting, the property cache contents will be read and
  // the critical selector info in the driver will be repopulated.
  ResetDriver();
  ValidateExpected("with_div_span", StrCat(css, "<span>Foo</span>"),
                   StrCat("<style>", critical_css_div_span, "</style>",
                          "<span>Foo</span>", LoadRestOfCss(css)));

  // Now send enough beacons to eliminate support for div; only span should be
  // left.
  CriticalSelectorFinder* finder = server_context()->critical_selector_finder();
  for (int i = 0; i < finder->SupportInterval(); ++i) {
    WriteCriticalSelectorsToPropertyCache(selectors);
    // We are sending enough beacons with the same selector set here that we
    // will enter low frequency beaconing mode, so advance time more to ensure
    // rebeaconing actually occurs.
    factory()->mock_timer()->AdvanceMs(
        options()->beacon_reinstrument_time_sec() * Timer::kSecondMs *
        kLowFreqBeaconMult);
  }
  ResetDriver();
  ValidateExpected("with_span", StrCat(css, "<span>Foo</span>"),
                   StrCat("<style>", critical_css_span, "</style>",
                          "<span>Foo</span>", LoadRestOfCss(css)));
}

TEST_F(CriticalSelectorFilterTest, RetainPseudoOnly) {
  // Make sure we handle things like :hover OK.
  GoogleString css = ":hover { border: 2px solid red; }";
  SetResponseWithDefaultHeaders("c.css", kContentTypeCss,
                                css, 100);
  ValidateExpected("hover", CssLinkHref("c.css"),
                   StrCat("<style>:hover{border:2px solid red}</style>",
                          LoadRestOfCss(CssLinkHref("c.css"))));
}

TEST_F(CriticalSelectorFilterTest, RetainUnparseable) {
  // Make sure we keep unparseable fragments around, particularly when
  // the problem is with the selector, as well as with the entire region.
  GoogleString css = "!huh! {background: white; } @huh { display: block; }";
  SetResponseWithDefaultHeaders("c.css", kContentTypeCss,
                                css, 100);
  ValidateExpected(
      "partly_unparseable", CssLinkHref("c.css"),
      StrCat("<style>!huh! {background:#fff}@huh { display: block; }</style>",
             LoadRestOfCss(CssLinkHref("c.css"))));
}

TEST_F(CriticalSelectorFilterTest, NoSelectorInfo) {
  // Particular CSS doesn't matter here, just want some.
  GoogleString css = "<style>div,span { display: inline-block; }</style>";

  // We shouldn't change things when there is no info on selectors available.
  page_->DeleteProperty(
      server_context()->beacon_cohort(),
      CriticalSelectorFinder::kCriticalSelectorsPropertyName);
  page_->WriteCohort(server_context()->beacon_cohort());

  ResetDriver();
  ValidateNoChanges("no_sel_info", StrCat(css, "<div>Foo</div>"));

  ValidateNoChanges("no_sel_info", StrCat(css, "<div>Foo</div>"));
  ValidateRewriterLogging(RewriterHtmlApplication::PROPERTY_CACHE_MISS);
}

TEST_F(CriticalSelectorFilterTest, ResolveUrlsProperly) {
  SetResponseWithDefaultHeaders("dir/c.css", kContentTypeCss,
                                "* { background-image: url(d.png); }", 100);
  ValidateExpected("rel_path", CssLinkHref("dir/c.css"),
                   StrCat("<style>*{background-image:url(dir/d.png)}</style>",
                          LoadRestOfCss(CssLinkHref("dir/c.css"))));
}

TEST_F(CriticalSelectorFilterTest, DoNotLazyLoadIfNothingRewritten) {
  // Make sure we don't do the whole 'lazy load rest of CSS' schpiel if we
  // did not end up changing the main CSS.
  SetupWaitFetcher();
  ValidateNoChanges("not_loaded", StrCat(CssLinkHref("a.css"),
                                         CssLinkHref("b.css")));
  CallFetcherCallbacks();
  // Skip ValidateRewriterLogging because fetcher interferes with WriteLog.
}

TEST_F(CriticalSelectorFilterTest, InlineAndAddStyleForFlushingEarly) {
  SetResponseWithDefaultHeaders("noscript.css", kContentTypeCss,
                                "noscript { border: 1px solid red; }", 100);

  GoogleString css = StrCat(
      "<style>*,p {display: none; } span {display: inline; }</style>",
      CssLinkHref("a.css"),
      "<noscript>", CssLinkHref("noscript.css"), "</noscript>",
      CssLinkHref("b.css"));

  GoogleString critical_css =
      "<style>*{display:none}</style>"  // from the inline
      "<style data-pagespeed-flush-style=\"0\">"
          "div,*::first-letter{display:block}</style>"  // from a.css
      "<noscript></noscript>"  // from noscript.css
      "<style data-pagespeed-flush-style=\"0\">"
          "@media screen{*{margin:0}}</style>";  // from b.css

  GoogleString input_html = StrCat(
      "<head>",
      css,
      "</head>"
      "<body><div>Stuff</div></body>");

  options()->ClearSignatureForTesting();
  options()->set_enable_flush_early_critical_css(true);
  options()->ComputeSignature();
  rewrite_driver()->set_flushing_early(true);
  // The "flushing_early" driver expects the critical CSS without the
  // full CSS at the bottom (no LoadRestOfCss).  This allows the flush
  // early flow to collect the CSS to flush.  The filter output is not
  // sent to the end user. (The "flushed_early" driver filters the
  // content that is sent to the user.)
  ValidateExpected(
      "flushing_early", input_html,
      StrCat("<head>", critical_css, "</head>",
             "<body><div>Stuff</div></body>"));
  ValidateRewriterLogging(RewriterHtmlApplication::ACTIVE);
}

TEST_F(CriticalSelectorFilterTest, InlineFlushEarly) {
  SetResponseWithDefaultHeaders("noscript.css", kContentTypeCss,
                                "noscript { border: 1px solid red; }", 100);

  GoogleString css_script = StrCat(
      "<style>*,p {display: none; } span {display: inline; }</style>",
      CssLinkHref("a.css"),
      CssLinkHrefMedia("b.css", "print,screen"));
  GoogleString css_noscript = StrCat(
      "<noscript>", CssLinkHref("noscript.css"), "</noscript>");

  GoogleString a_url = "http://test.com/a.css";
  GoogleString b_url = "http://test.com/b.css";
  GoogleString a_style_id =
      rewrite_driver()->server_context()->hasher()->Hash(a_url);
  GoogleString b_style_id =
      rewrite_driver()->server_context()->hasher()->Hash(b_url);
  GoogleString critical_css = StrCat(
      "<style>*{display:none}</style>"  // from the inline
      "<script id=\"psa_flush_style_early\" data-pagespeed-no-defer"
      " type=\"text/javascript\">",
      CriticalSelectorFilter::kApplyFlushEarlyCss,
      "</script>"
      "<script data-pagespeed-no-defer type=\"text/javascript\">",
      StringPrintf(CriticalSelectorFilter::kInvokeFlushEarlyCssTemplate,
                   a_style_id.c_str(), "" /* media */),
      "</script>"  // from a.css
      "<script data-pagespeed-no-defer type=\"text/javascript\">",
      StringPrintf(CriticalSelectorFilter::kInvokeFlushEarlyCssTemplate,
                   b_style_id.c_str(), "screen" /* media */),
      "</script>"  // from b.css
      "<noscript></noscript>");  // from noscript.css

  GoogleString html = StrCat(
      "<head>",
      css_script,
      css_noscript,
      "</head>"
      "<body><div>Stuff</div></body>");

  options()->ClearSignatureForTesting();
  options()->set_enable_flush_early_critical_css(true);
  options()->ComputeSignature();

  rewrite_driver()->flush_early_info()->set_resource_html(
      CssLinkHref("\"" + a_url + "\"") +
      CssLinkHref("\"" + b_url + "\""));

  rewrite_driver()->set_flushed_early(true);

  ValidateExpected(
      "flushed_early", html,
      StrCat("<head>", critical_css, "</head>",
             "<body><div>Stuff</div>",
             WrapForJsLoad(css_script),
             css_noscript,
             JsLoader(),
             "</body>"));
  ValidateRewriterLogging(RewriterHtmlApplication::ACTIVE);
}

class CriticalSelectorWithRewriteCssFilterTest
    : public CriticalSelectorFilterTest {
 protected:
  virtual void SetUp() {
    options()->EnableFilter(RewriteOptions::kRewriteCss);
    CriticalSelectorFilterTest::SetUp();
  }
};

TEST_F(CriticalSelectorWithRewriteCssFilterTest, ProperlyUsedOptimized) {
  // Make sure that the lazy loading code for rest of CSS actually uses
  // optimized resources.
  GoogleString css = StrCat(
      CssLinkHref("a.css"),
      CssLinkHref("b.css"));

  GoogleString critical_css =
      "<style>div,*::first-letter{display:block}</style>"  // from a.css
      "<style>@media screen{*{margin:0}}</style>";  // from b.css

  GoogleString optimized_css = StrCat(
      CssLinkHref(Encode("", "cf", "0", "a.css", "css")),
      CssLinkHref(Encode("", "cf", "0", "b.css", "css")));
  GoogleString html = StrCat(
      "<head>",
      css,
      "</head>"
      "<body><div>Stuff</div></body>");

  ValidateExpected("with_rewrite_css",
                   html,
                   StrCat("<head>", critical_css, "</head>"
                          "<body><div>Stuff</div>",
                          LoadRestOfCss(optimized_css), "</body>"));
}

class CriticalSelectorWithCombinerFilterTest
    : public CriticalSelectorFilterTest {
 protected:
  virtual void SetUp() {
    options()->EnableFilter(RewriteOptions::kCombineCss);
    CriticalSelectorFilterTest::SetUp();
  }
};

TEST_F(CriticalSelectorWithCombinerFilterTest, Interaction) {
  GoogleString css = StrCat(
      CssLinkHref("a.css"),
      CssLinkHref("b.css"));

  // Only one <style> element since combine_css ran before us.
  GoogleString critical_css =
      "<style>div,*::first-letter{display:block}"  // from a.css
      "@media screen{*{margin:0}}</style>";  // from b.css

  GoogleString combined_url = Encode("", "cc", "0",
                                     MultiUrl("a.css", "b.css"), "css");

  ValidateExpected("with_combiner",
                   css,
                   StrCat(critical_css,
                          LoadRestOfCss(CssLinkHref(combined_url))));
}

TEST_F(CriticalSelectorWithCombinerFilterTest, ResolveWhenCombineAcrossPaths) {
  // Make sure we get proper URL resolution when doing combine-across-paths.
  SetResponseWithDefaultHeaders("dir/a.css", kContentTypeCss,
                                "* { background-image: url(/dir/d.png); }",
                                100);
  GoogleString css = StrCat(
      CssLinkHref("dir/a.css"),
      CssLinkHref("b.css"));

    // Only one <style> element since combine_css ran before us.
  GoogleString critical_css =
      "<style>*{background-image:url(dir/d.png)}"  // from dir/a.css
      "@media screen{*{margin:0}}</style>";  // from b.css

  GoogleString combined_url = "dir,_a.css+b.css.pagespeed.cc.0.css";

  ValidateExpected("with_combiner_rel",
                   css,
                   StrCat(critical_css,
                          LoadRestOfCss(CssLinkHref(combined_url))));
}

class CriticalSelectorWithInlineCssFilterTest
    : public CriticalSelectorFilterTest {
 protected:
  virtual void SetUpBeforeSelectorsFilter() {}

  // Add the inline css filter after the critical selector filter so
  // it matches the order that is in RewriteDriver.
  virtual void SetUpAfterSelectorsFilter() {
    options()->EnableFilter(RewriteOptions::kInlineCss);
    rewrite_driver()->AddFilters();
  }
};

// When CriticalSelectorFilter and InlineCss are both enabled, only
// CriticalSelectorFilter will be applied.
TEST_F(CriticalSelectorWithInlineCssFilterTest, AvoidTryingToInlineTwice) {
  GoogleString css = StrCat(
      CssLinkHref("a.css"),
      CssLinkHref("b.css"));
  GoogleString critical_css =
      "<style>div,*::first-letter{display:block}</style>"  // from a.css
      "<style>@media screen{*{margin:0}}</style>";  // from b.css

  GoogleString input_html = StrCat(
      "<head>", css, "</head>"
      "<body><div>Stuff</div></body>");
  GoogleString expected_html = StrCat(
      "<head>", critical_css, "</head>"
      "<body><div>Stuff</div>", LoadRestOfCss(css), "</body>");
  ValidateExpected("with_inline_css", input_html, expected_html);
}

class CriticalSelectorWithBackgroundImageCacheExtensionTest
    : public CriticalSelectorFilterTest {
 protected:
  virtual void SetUp() {
    options()->EnableFilter(RewriteOptions::kExtendCacheImages);
    options()->EnableFilter(RewriteOptions::kRewriteCss);
    CriticalSelectorFilterTest::SetUp();
  }
};

// Specific test for a bug where inline style blocks would not be treated
// correctly. Even though they should have been rewritten by rewrite_css,
// the unoptimized <style> block would be copied to the bottom of the page.
TEST_F(CriticalSelectorWithBackgroundImageCacheExtensionTest,
       DontMixUnoptAndOptStyles) {
  // Triggers calling InlineOutputResource::url().
  options()->ClearSignatureForTesting();
  options()->set_enable_cache_purge(true);
  options()->ComputeSignature();

  SetResponseWithDefaultHeaders("background.png", kContentTypePng,
                                "Dummy contents", 100);
  SetResponseWithDefaultHeaders("extern.css", kContentTypeCss,
                                "* {background: url(background.png)}\n"
                                ".not-critical { margin: 0 }", 100);

  GoogleString input_css = StrCat(
      "  <style>div { background: url(background.png) }"
      ".not-critical { color: red; }</style>\n"
      "  ", CssLinkHref("extern.css"), "\n");

  GoogleString critical_css = StrCat(
      "  <style>div{background:url(",
      Encode("", "ce", "0", "background.png", "png"), ")}</style>\n"
      "  <style>*{background:url(",
      Encode("", "ce", "0", "background.png", "png"), ")}</style>\n");

  // Both inline and external CSS should be rewritten here.
  GoogleString rewritten_css = StrCat(
      "<style>div{background:url(",
      Encode("", "ce", "0", "background.png", "png"), ")}"
      ".not-critical{color:red}</style>",
      CssLinkHref(Encode("", "cf", "0", "extern.css", "css")));

  GoogleString input_html = StrCat(
      "<head>\n",
      input_css,
      "</head>\n"
      "<body>\n"
      "  <div>Foo</div>\n"
      "  <span>Bar</span>\n"
      "</body>\n");
  GoogleString expected_html = StrCat(
      "<head>\n",
      critical_css,
      "</head>\n"
      "<body>\n"
      "  <div>Foo</div>\n"
      "  <span>Bar</span>\n",
      LoadRestOfCss(rewritten_css),
      "</body>\n");
  ValidateExpected("dont_mix_unopt_and_opt", input_html, expected_html);
}

}  // namespace

}  // namespace net_instaweb
