/*
 * Copyright 2012 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: bharathbhushan@google.com (Bharath Bhushan)

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

#include "base/logging.h"
#include "net/instaweb/http/public/log_record.h"
#include "net/instaweb/http/public/logging_proto_impl.h"
#include "net/instaweb/rewriter/flush_early.pb.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 "pagespeed/kernel/base/gtest.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/base/timer.h"
#include "pagespeed/kernel/http/response_headers.h"
#include "pagespeed/kernel/http/user_agent_matcher_test_base.h"
#include "pagespeed/opt/logging/enums.pb.h"

// TODO(bharathbhushan): Test interaction with the flush early flow and related
// filters.
// TODO(bharathbhushan): Have a test to ensure that this is the last post render
// filter.
// TODO(bharathbhushan): Add a test for noscript.

namespace {
const int64 kOriginTtlMs = 12 * net_instaweb::Timer::kMinuteMs;
const char kJsData[] =
    "alert     (    'hello, world!'    ) "
    " /* removed */ <!-- removed --> "
    " // single-line-comment";
}

namespace net_instaweb {

class InsertDnsPrefetchFilterTest : public RewriteTestBase {
 public:
  InsertDnsPrefetchFilterTest() : writer_(&output_) {}

 protected:
  virtual void SetUp() {
    options()->set_support_noscript_enabled(false);
    options()->EnableFilter(RewriteOptions::kInsertDnsPrefetch);
    RewriteTestBase::SetUp();
    rewrite_driver()->AddFilters();
    rewrite_driver()->SetWriter(&writer_);
    SetCurrentUserAgent(UserAgentMatcherTestBase::kChromeUserAgent);
  }

  virtual void TearDown() {
    filter_.reset(NULL);
    RewriteTestBase::TearDown();
  }

  void CheckPrefetchInfo(int num_domains_in_current_rewrite,
             int num_domains_in_previous_rewrite,
             int num_domains_to_store, const GoogleString& stored_domains_str) {
    StringPieceVector stored_domains;
    SplitStringPieceToVector(stored_domains_str, ",", &stored_domains, true);
    ASSERT_EQ(num_domains_to_store, stored_domains.size());
    FlushEarlyInfo* info = rewrite_driver()->flush_early_info();
    EXPECT_EQ(num_domains_in_current_rewrite,
              info->total_dns_prefetch_domains());
    EXPECT_EQ(num_domains_in_previous_rewrite,
              info->total_dns_prefetch_domains_previous());
    EXPECT_EQ(num_domains_to_store, info->dns_prefetch_domains_size());
    for (int i = 0; i < info->dns_prefetch_domains_size(); ++i) {
      EXPECT_EQ(stored_domains[i], info->dns_prefetch_domains(i));
    }
  }

  void CheckLogStatus(RewriterHtmlApplication::Status html_status) {
    rewrite_driver_->log_record()->WriteLog();
    for (int i = 0; i < logging_info()->rewriter_stats_size(); i++) {
      if (logging_info()->rewriter_stats(i).id() ==
          RewriteOptions::FilterId(RewriteOptions::kInsertDnsPrefetch) &&
          logging_info()->rewriter_stats(i).has_html_status()) {
        EXPECT_EQ(html_status, logging_info()->rewriter_stats(i).html_status());
        return;
      }
    }
    FAIL();
  }

  void CheckLogStatus(RewriterHtmlApplication::Status html_status,
                      RewriterApplication::Status app_status,
                      int app_status_count) {
    rewrite_driver_->log_record()->WriteLog();
    for (int i = 0; i < logging_info()->rewriter_stats_size(); i++) {
      if (logging_info()->rewriter_stats(i).id() ==
          RewriteOptions::FilterId(RewriteOptions::kInsertDnsPrefetch) &&
          logging_info()->rewriter_stats(i).has_html_status()) {
        EXPECT_EQ(html_status, logging_info()->rewriter_stats(i).html_status());
        const RewriteStatusCount& count_applied =
            logging_info()->rewriter_stats(i).status_counts(0);
        EXPECT_EQ(app_status, count_applied.application_status());
        EXPECT_EQ(app_status_count, count_applied.count());
        return;
      }
    }
    FAIL();
  }

  GoogleString CreateHtml(int num_scripts) {
    GoogleString html = "<head><script></script></head><body>";
    for (int i = 1; i <= num_scripts; ++i) {
      StrAppend(&html, "<script src=\"http://", IntegerToString(i),
                ".com/\"/>");
    }
    StrAppend(&html, "</body>");
    return html;
  }

  GoogleString CreateHtmlWithPrefetchTags(int num_scripts, int num_tags) {
    GoogleString html = "<head><script></script>";
    for (int i = 1; i <= num_tags; ++i) {
      StrAppend(&html, "<link rel=\"dns-prefetch\" href=\"//",
                IntegerToString(i), ".com\">");
    }
    StrAppend(&html, "</head><body>");
    for (int i = 1; i <= num_scripts; ++i) {
      StrAppend(&html, "<script src=\"http://", IntegerToString(i),
                ".com/\"/>");
    }
    html += "</body>";
    return html;
  }

  GoogleString CreateDomainsVector(int num_domains) {
    GoogleString result;
    for (int i = 1; i <= num_domains; ++i) {
      StrAppend(&result, IntegerToString(i), ".com,");
    }
    LOG(INFO) << "CreateDomainsVector: " << result;
    return result;
  }

  GoogleString output_;

 private:
  StringWriter writer_;
  ResponseHeaders headers_;
  scoped_ptr<InsertDnsPrefetchFilter> filter_;

  DISALLOW_COPY_AND_ASSIGN(InsertDnsPrefetchFilterTest);
};

TEST_F(InsertDnsPrefetchFilterTest, IgnoreDomainsInHead) {
  GoogleString html =
      "<head>"
        "<link type=\"text/css\" rel=\"stylesheet\" href=\"http://a.com/\">"
        "<script src=\"http://b.com/\"/>"
        "<link rel=\"dns-prefetch\" href=\"http://c.com\">"
      "</head><body></body>";
  Parse("ignore_domains_in_head", html);
  EXPECT_EQ(AddHtmlBody(html), output_);
  CheckPrefetchInfo(0, 0, 0, "");
}

TEST_F(InsertDnsPrefetchFilterTest, StoreDomainsInBody) {
  GoogleString html =
      "<head></head>"
      "<body>"
        "<link type=\"text/css\" rel=\"stylesheet\" href=\"http://a.com/\">"
        "<script src=\"http://b.com/\"/>"
        "<img src=\"http://c.com/\"/>"
      "</body>";
  Parse("store_domains_in_body", html);
  EXPECT_EQ(AddHtmlBody(html), output_);
  CheckPrefetchInfo(3, 0, 3, "a.com,b.com,c.com");
}

TEST_F(InsertDnsPrefetchFilterTest, IgnoreCurrentDomain) {
  GoogleString html = StrCat(
      "<head></head>"
      "<body>"
      "<link type=\"text/css\" rel=\"stylesheet\" href=\"",
      AbsolutifyUrl("style.css"),
      "\">"
      "<script src=\"",
      AbsolutifyUrl("script.js"),
      "\">"
      "<img src=\"",
      AbsolutifyUrl("img.src"),
      "\">"
      "</body>");
  Parse("ignore_current_domain", html);
  EXPECT_EQ(AddHtmlBody(html), output_);
  CheckPrefetchInfo(0, 0, 0, "");
}

TEST_F(InsertDnsPrefetchFilterTest,
       DisableInsertDnsPrefetchForUserAgentsNotSupported) {
  SetCurrentUserAgent("");
  GoogleString html =
      "<head></head>"
      "<body>"
        "<link type=\"text/css\" rel=\"stylesheet\" href=\"http://a.com/\">"
        "<script src=\"http://b.com/\"/>"
        "<img src=\"http://c.com/\"/>"
      "</body>";
  Parse("store_domains_in_body", html);
  EXPECT_EQ(AddHtmlBody(html), output_);
  CheckPrefetchInfo(0, 0, 0, "");
  CheckLogStatus(RewriterHtmlApplication::USER_AGENT_NOT_SUPPORTED);
}

TEST_F(InsertDnsPrefetchFilterTest, StoreDomainsOnlyInBody) {
  GoogleString html =
      "<head>"
        "<script src=\"http://b.com/\"/>"
      "</head>"
      "<body>"
        "<link type=\"text/css\" rel=\"stylesheet\" href=\"http://a.com/\">"
        "<script src=\"http://b.com/\"/>"
        "<img src=\"http://c.com/\"/>"
      "</body>";
  Parse("store_domains_in_body", html);
  EXPECT_EQ(AddHtmlBody(html), output_);
  // b.com is not stored since it is already in HEAD.
  CheckPrefetchInfo(2, 0, 2, "a.com,c.com");
}

TEST_F(InsertDnsPrefetchFilterTest, StoreDomainsInBodyMax) {
  GoogleString html(CreateHtml(10));
  Parse("store_domains_in_body_max", html);
  EXPECT_EQ(AddHtmlBody(html), output_);
  // Only 8/10 domains get stored.
  CheckPrefetchInfo(10, 0, 8, CreateDomainsVector(8));
}

// TODO(bharathbhushan): Add tests for all the html tags which can have URI
// attributes.
TEST_F(InsertDnsPrefetchFilterTest, LinkTagTest) {
  GoogleString html =
      "<head>"
        "<script></script>"
        "<link rel=\"alternate\" href=\"http://a.com\">"
        "<link rel=\"author\" href=\"http://b.com\">"
        "<link rel=\"dns-prefetch\" href=\"http://c.com\">"
        "<link rel=\"help\" href=\"http://d.com\">"
        "<link rel=\"icon\" href=\"http://e.com\">"
        "<link rel=\"license\" href=\"http://f.com\">"
        "<link rel=\"next\" href=\"http://g.com\">"
        "<link rel=\"prefetch\" href=\"http://h.com\">"
        "<link rel=\"prev\" href=\"http://i.com\">"
        "<link rel=\"search\" href=\"http://j.com\">"
        "<link rel=\"stylesheet\" href=\"http://k.com\">"
      "</head>"
      "<body>"
        "<script src=\"http://a.com/\"/>"
        "<script src=\"http://b.com/\"/>"
        "<script src=\"http://c.com/\"/>"
        "<script src=\"http://d.com/\"/>"
        "<script src=\"http://e.com/\"/>"
        "<script src=\"http://f.com/\"/>"
        "<script src=\"http://g.com/\"/>"
        "<script src=\"http://h.com/\"/>"
        "<script src=\"http://i.com/\"/>"
        "<script src=\"http://j.com/\"/>"
        "<script src=\"http://k.com/\"/>"
      "</body>";
  Parse("test_different_link_tags", html);
  EXPECT_EQ(AddHtmlBody(html), output_);
  // The following link types are for resources or relevant to DNS prefetch
  // tags: dns-prefetch, icon, prefetch, stylesheet. The domains in those tags
  // are not stored. The rest of link types have hyperlinks and their domains
  // get stored.
  CheckPrefetchInfo(7, 0, 7, "a.com,b.com,d.com,f.com,g.com,i.com,j.com");
}

TEST_F(InsertDnsPrefetchFilterTest, FullFlowTest) {
  GoogleString html_input = CreateHtml(10);
  Parse("store_8_of_10", html_input);
  EXPECT_EQ(AddHtmlBody(html_input), output_);
  CheckPrefetchInfo(10, 0, 8, CreateDomainsVector(8));
  output_.clear();

  html_input = CreateHtml(9);
  Parse("store_8_of_9", html_input);
  EXPECT_EQ(AddHtmlBody(html_input), output_);
  CheckPrefetchInfo(9, 10, 8, CreateDomainsVector(8));
  output_.clear();

  html_input = CreateHtml(6);
  // 8 DNS prefetch tags inserted since the difference in the number of domains
  // in the last two rewrites (10, 9) is <= 2 and we had stored 8 domains in the
  // previous rewrite. This is the common case.
  // In this rewrite we have an unstable response, whose effect shows up in the
  // next rewrite.
  GoogleString html_output = CreateHtmlWithPrefetchTags(6, 8);
  Parse("stable_domain_list_so_insert_tags", html_input);
  EXPECT_EQ(AddHtmlBody(html_output), output_);
  CheckPrefetchInfo(6, 9, 6, CreateDomainsVector(6));
  output_.clear();
  CheckLogStatus(RewriterHtmlApplication::ACTIVE,
                 RewriterApplication::APPLIED_OK,
                 8);

  // Since the last response caused instability in the domain list, we don't
  // insert any prefetch tags in this rewrite.
  Parse("after_unstable_response", html_input);
  EXPECT_EQ(AddHtmlBody(html_input), output_);
  CheckPrefetchInfo(6, 6, 6, CreateDomainsVector(6));
  output_.clear();
}

TEST_F(InsertDnsPrefetchFilterTest, FullFlowTestForLogging) {
  GoogleString html_input = CreateHtml(10);
  Parse("store_8_of_10", html_input);
  EXPECT_EQ(AddHtmlBody(html_input), output_);
  CheckPrefetchInfo(10, 0, 8, CreateDomainsVector(8));
  output_.clear();

  html_input = CreateHtml(9);
  Parse("store_8_of_9", html_input);
  EXPECT_EQ(AddHtmlBody(html_input), output_);
  CheckPrefetchInfo(9, 10, 8, CreateDomainsVector(8));
  CheckLogStatus(RewriterHtmlApplication::ACTIVE,
                 RewriterApplication::NOT_APPLIED,
                 1);
  output_.clear();
}

TEST_F(InsertDnsPrefetchFilterTest, InsertDnsPrefetchFilterWithOtherFilters) {
  options()->ClearSignatureForTesting();
  options()->EnableFilter(RewriteOptions::kDeferJavascript);
  options()->EnableFilter(RewriteOptions::kLazyloadImages);
  options()->EnableFilter(RewriteOptions::kDelayImages);
  server_context()->ComputeSignature(options());
  GoogleString html =
      "<head>"
        "<script src=\"http://b.com/\"/>"
      "</head>"
      "<body>"
        "<link type=\"text/css\" rel=\"stylesheet\" href=\"http://a.com/\">"
        "<script src=\"http://b.com/\"/>"
        "<img src=\"http://c.com/\"/>"
      "</body>";
  Parse("store_domains_in_body", html);
  EXPECT_EQ(AddHtmlBody(html), output_);
  // b.com is not stored since it is already in HEAD.
  CheckPrefetchInfo(2, 0, 2, "a.com,c.com");
}

TEST_F(InsertDnsPrefetchFilterTest, InsertDomainsinHeadForFlushEarlyFlow) {
  options()->ClearSignatureForTesting();
  options()->EnableFilter(RewriteOptions::kFlushSubresources);
  server_context()->ComputeSignature(options());
  GoogleString html =
      "<head>"
        "<script src=\"http://b.com/\"/>"
      "<script src=\"http://d.com/\"/>"
      "</head>"
      "<body>"
        "<link type=\"text/css\" rel=\"stylesheet\" href=\"http://a.com/\">"
        "<script src=\"http://b.com/\"/>"
        "<img src=\"http://c.com/\"/>"
      "</body>";
  Parse("store_domains_in_body", html);
  EXPECT_EQ(AddHtmlBody(html), output_);
  CheckPrefetchInfo(4, 0, 4, "b.com,d.com,a.com,c.com");
}

TEST_F(InsertDnsPrefetchFilterTest, NoDomainsWhileFlushingEarly) {
  rewrite_driver()->set_flushing_early(true);
  GoogleString html =
      "<head>"
        "<script src=\"http://b.com/\"/>"
      "</head>"
      "<body>"
        "<link type=\"text/css\" rel=\"stylesheet\" href=\"http://a.com/\">"
        "<script src=\"http://b.com/\"/>"
        "<img src=\"http://c.com/\"/>"
      "</body>";
  Parse("store_domains_in_body", html);
  EXPECT_EQ(AddHtmlBody(html), output_);
  CheckPrefetchInfo(0, 0, 0, "");
}

}  // namespace net_instaweb
