/*
 * 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: jmaessen@google.com (Jan-Willem Maessen)

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

#include "base/logging.h"
#include "net/instaweb/rewriter/critical_images.pb.h"
#include "net/instaweb/rewriter/critical_keys.pb.h"
#include "net/instaweb/rewriter/public/critical_finder_support_util.h"
#include "net/instaweb/rewriter/public/critical_images_finder.h"
#include "net/instaweb/rewriter/public/critical_images_finder_test_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/test_rewrite_driver_factory.h"
#include "net/instaweb/util/public/property_cache.h"
#include "pagespeed/kernel/base/gmock.h"
#include "pagespeed/kernel/base/gtest.h"
#include "pagespeed/kernel/base/mock_timer.h"
#include "pagespeed/kernel/base/timer.h"

using ::testing::Eq;

namespace net_instaweb {

namespace {

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

class BeaconCriticalImagesFinderTest : public CriticalImagesFinderTestBase {
 public:
  virtual CriticalImagesFinder* finder() { return finder_; }

 protected:
  BeaconCriticalImagesFinderTest() { }

  virtual void SetUp() {
    CriticalImagesFinderTestBase::SetUp();
    const PropertyCache::Cohort* beacon_cohort =
        SetupCohort(page_property_cache(), RewriteDriver::kBeaconCohort);
    server_context()->set_beacon_cohort(beacon_cohort);
    finder_ = new BeaconCriticalImagesFinder(
        beacon_cohort, factory()->nonce_generator(), statistics());
    server_context()->set_critical_images_finder(finder_);
    ResetDriver();
    SetDriverRequestHeaders();
    // Set up default critical image sets to use for testing.
    html_images_.insert("x.jpg");
    html_images_.insert("y.png");
    html_images_.insert("z.gif");
    css_images_.insert("a.jpg");
    css_images_.insert("b.png");
    css_images_.insert("c.gif");
  }

  void WriteToPropertyCache() {
    rewrite_driver()->property_page()->WriteCohort(
        server_context()->beacon_cohort());
  }

  void WriteBackAndResetDriver() {
    WriteToPropertyCache();
    ResetDriver();
    SetDriverRequestHeaders();
  }

  GoogleString CriticalImagesString() {
    WriteBackAndResetDriver();
    const StringSet& html_images =
        finder_->GetHtmlCriticalImages(rewrite_driver());
    const StringSet& css_images =
        finder_->GetCssCriticalImages(rewrite_driver());
    GoogleString result = JoinCollection(html_images, ",");
    StrAppend(&result, ";");
    AppendJoinCollection(&result, css_images, ",");
    return result;
  }

  // Simulate beacon insertion.
  void Beacon() {
    WriteBackAndResetDriver();
    factory()->mock_timer()->AdvanceMs(
        options()->beacon_reinstrument_time_sec() * Timer::kSecondMs);
    VerifyBeaconStatus(kBeaconWithNonce);
  }

  // Same as Beacon(), but advances time by the low frequency beacon interval.
  // Useful in cases where a lot of beacons with the same critical image set are
  // being sent.
  void BeaconLowFrequency() {
    WriteBackAndResetDriver();
    factory()->mock_timer()->AdvanceMs(
        options()->beacon_reinstrument_time_sec() * Timer::kSecondMs *
        kLowFreqBeaconMult);
    VerifyBeaconStatus(kBeaconWithNonce);
  }

  // Verify that no beacon injection occurs.
  void VerifyNoBeaconing() {
    VerifyBeaconStatus(kDoNotBeacon);
  }

  // Verify that beacon injection occurs.
  void VerifyBeaconing() {
    VerifyBeaconStatus(kBeaconWithNonce);
  }

  // Helper method used for verifying beacon injection status.
  void VerifyBeaconStatus(BeaconStatus status) {
    bool status_is_beacon_with_nonce = (status == kBeaconWithNonce);
    EXPECT_THAT(finder_->ShouldBeacon(rewrite_driver()),
                Eq(status_is_beacon_with_nonce));
    last_beacon_metadata_ =
        finder_->PrepareForBeaconInsertion(rewrite_driver());
    EXPECT_EQ(status, last_beacon_metadata_.status);
    if (status == kBeaconWithNonce) {
      EXPECT_STREQ(ExpectedNonce(), last_beacon_metadata_.nonce);
    } else {
      EXPECT_TRUE(last_beacon_metadata_.nonce.empty());
    }
  }

  CriticalImages* GetCriticalImages() {
    WriteBackAndResetDriver();
    EXPECT_TRUE(finder()->IsCriticalImageInfoPresent(rewrite_driver()));
    return &rewrite_driver()->critical_images_info()->proto;
  }

  void CheckDefaultBeaconSupport(int support) {
    CheckAXBeaconSupport(support, support, support);
  }

  void CheckAXBeaconSupport(int a_support, int x_support, int other_support) {
    // Inspect support values in the critical images protobuf.
    const CriticalImages* critical_images = GetCriticalImages();
    const CriticalKeys& html_keys =
        critical_images->html_critical_image_support();
    const CriticalKeys& css_keys =
        critical_images->css_critical_image_support();
    ASSERT_EQ(3, html_keys.key_evidence_size());
    EXPECT_EQ("x.jpg", html_keys.key_evidence(0).key());
    EXPECT_EQ(x_support, html_keys.key_evidence(0).support());
    EXPECT_EQ("y.png", html_keys.key_evidence(1).key());
    EXPECT_EQ(other_support, html_keys.key_evidence(1).support());
    EXPECT_EQ("z.gif", html_keys.key_evidence(2).key());
    EXPECT_EQ(other_support, html_keys.key_evidence(2).support());
    ASSERT_EQ(3, css_keys.key_evidence_size());
    EXPECT_EQ("a.jpg", css_keys.key_evidence(0).key());
    EXPECT_EQ(a_support, css_keys.key_evidence(0).support());
    EXPECT_EQ("b.png", css_keys.key_evidence(1).key());
    EXPECT_EQ(other_support, css_keys.key_evidence(1).support());
    EXPECT_EQ("c.gif", css_keys.key_evidence(2).key());
    EXPECT_EQ(other_support, css_keys.key_evidence(2).support());
  }

  bool UpdateCriticalImagesCacheEntry(
      const StringSet* html_critical_images_set,
      const StringSet* css_critical_images_set) {
    // If this fails, you should have called Beacon().
    CHECK_EQ(kBeaconWithNonce, last_beacon_metadata_.status);
    return UpdateCriticalImagesCacheEntry(
        html_critical_images_set, css_critical_images_set,
        last_beacon_metadata_.nonce);
  }

  bool UpdateCriticalImagesCacheEntry(
      const StringSet* html_critical_images_set,
      const StringSet* css_critical_images_set,
      const GoogleString& nonce) {
    EXPECT_FALSE(nonce.empty());
    return finder_->UpdateCriticalImagesCacheEntry(
        html_critical_images_set, css_critical_images_set, NULL,
        nonce, server_context()->beacon_cohort(),
        rewrite_driver()->property_page(), server_context()->timer());
  }

  BeaconCriticalImagesFinder* finder_;
  BeaconMetadata last_beacon_metadata_;
  StringSet html_images_;
  StringSet css_images_;
};

TEST_F(BeaconCriticalImagesFinderTest, StoreRestore) {
  // Before beacon insertion, nothing in pcache.
  CheckCriticalImageFinderStats(0, 0, 0);
  CriticalImagesInfo* read_images =
      rewrite_driver()->critical_images_info();
  EXPECT_TRUE(read_images == NULL);
  // Force computation of critical_images_info() via CriticalImagesString()
  EXPECT_STREQ(";", CriticalImagesString());
  read_images = rewrite_driver()->critical_images_info();
  EXPECT_TRUE(read_images != NULL);
  // Now beacon and register some critical image results.
  Beacon();
  CheckCriticalImageFinderStats(0, 0, 2);
  EXPECT_TRUE(UpdateCriticalImagesCacheEntry(&html_images_, &css_images_));
  // Check actual support values, but also verify that images are considered
  // critical.
  CheckDefaultBeaconSupport(finder_->SupportInterval());
  EXPECT_STREQ("x.jpg,y.png,z.gif;a.jpg,b.png,c.gif", CriticalImagesString());
  CheckCriticalImageFinderStats(2, 0, 2);
  // Now test expiration.
  WriteBackAndResetDriver();
  AdvanceTimeMs(2 * options()->finder_properties_cache_expiration_time_ms());
  read_images = rewrite_driver()->critical_images_info();
  EXPECT_TRUE(read_images == NULL);
  // Force computation of critical_images_info() via CriticalImagesString()
  EXPECT_STREQ(";", CriticalImagesString());
  CheckCriticalImageFinderStats(2, 1, 2);
}

// Verify that writing multiple beacon results are stored and aggregated. The
// critical selector set should contain all images seen in the last
// SupportInterval() beacon responses.  After SupportInterval() responses,
// beacon results only seen once should no longer be considered critical.
TEST_F(BeaconCriticalImagesFinderTest, StoreMultiple) {
  Beacon();
  EXPECT_TRUE(UpdateCriticalImagesCacheEntry(&html_images_, &css_images_));
  EXPECT_STREQ("x.jpg,y.png,z.gif;a.jpg,b.png,c.gif", CriticalImagesString());
  CheckDefaultBeaconSupport(finder_->SupportInterval());

  html_images_.clear();
  html_images_.insert("x.jpg");
  css_images_.clear();
  css_images_.insert("a.jpg");
  for (int i = 0; i < finder_->SupportInterval() - 1; ++i) {
    BeaconLowFrequency();
    EXPECT_TRUE(UpdateCriticalImagesCacheEntry(&html_images_, &css_images_));
    EXPECT_STREQ("x.jpg;a.jpg", CriticalImagesString());
  }

  // We send two more beacon responses, which should kick a.jpg out of the
  // critical css images set as it falls below the 80% support threshold.  y.png
  // will not accumulate enough support to be considered critical.
  css_images_.clear();
  html_images_.insert("y.png");
  for (int i = 0; i < 2; ++i) {
    BeaconLowFrequency();
    EXPECT_TRUE(UpdateCriticalImagesCacheEntry(&html_images_, &css_images_));
  }
  EXPECT_STREQ("x.jpg;", CriticalImagesString());
}

// Make sure beacon results can arrive out of order (so long as the nonce
// doesn't time out).
TEST_F(BeaconCriticalImagesFinderTest, OutOfOrder) {
  // Make sure that the rebeaconing time is less than the time a nonce is valid,
  // so that we can test having multiple outstanding nonces.
  options()->set_beacon_reinstrument_time_sec(kBeaconTimeoutIntervalMs /
                                              Timer::kSecondMs / 2);
  Beacon();
  GoogleString initial_nonce(last_beacon_metadata_.nonce);
  // A second beacon occurs and the result comes back first.
  Beacon();
  EXPECT_TRUE(UpdateCriticalImagesCacheEntry(&html_images_, &css_images_));
  EXPECT_STREQ("x.jpg,y.png,z.gif;a.jpg,b.png,c.gif", CriticalImagesString());
  CheckDefaultBeaconSupport(finder_->SupportInterval());
  // Now the first beacon result comes back out of order.  It should still work.
  html_images_.clear();
  html_images_.insert("x.jpg");
  css_images_.clear();
  css_images_.insert("a.jpg");
  EXPECT_TRUE(UpdateCriticalImagesCacheEntry(
      &html_images_, &css_images_, initial_nonce));
  EXPECT_STREQ("x.jpg;a.jpg", CriticalImagesString());
  int supportedTwice = 2 * finder_->SupportInterval() - 1;
  CheckAXBeaconSupport(supportedTwice, supportedTwice,
                       finder_->SupportInterval() - 1);
  // A duplicate beacon nonce will be dropped, and support won't change.
  EXPECT_FALSE(UpdateCriticalImagesCacheEntry(&html_images_, &css_images_));
  EXPECT_STREQ("x.jpg;a.jpg", CriticalImagesString());
  CheckAXBeaconSupport(supportedTwice, supportedTwice,
                       finder_->SupportInterval() - 1);
  // As will an entirely bogus nonce (here we use non-base64 characters).
  const char kBogusNonce[] = "*&*";
  EXPECT_FALSE(UpdateCriticalImagesCacheEntry(
      &html_images_, &css_images_, kBogusNonce));
  EXPECT_STREQ("x.jpg;a.jpg", CriticalImagesString());
  CheckAXBeaconSupport(supportedTwice, supportedTwice,
                       finder_->SupportInterval() - 1);
}

TEST_F(BeaconCriticalImagesFinderTest, NonceTimeout) {
  // Make sure that beacons time out after kBeaconTimeoutIntervalMs.
  Beacon();
  GoogleString initial_nonce(last_beacon_metadata_.nonce);
  // beacon_reinstrument_time_sec() passes (in mock time) before the next call
  // completes:
  Beacon();
  factory()->mock_timer()->AdvanceMs(kBeaconTimeoutIntervalMs);
  // This beacon arrives right at its deadline, and is OK.
  EXPECT_TRUE(UpdateCriticalImagesCacheEntry(&html_images_, &css_images_));
  EXPECT_STREQ("x.jpg,y.png,z.gif;a.jpg,b.png,c.gif", CriticalImagesString());
  CheckDefaultBeaconSupport(finder_->SupportInterval());
  // The first beacon arrives after its deadline, and is dropped.
  html_images_.clear();
  html_images_.insert("x.jpg");
  css_images_.clear();
  css_images_.insert("a.jpg");
  EXPECT_FALSE(UpdateCriticalImagesCacheEntry(
      &html_images_, &css_images_, initial_nonce));
  EXPECT_STREQ("x.jpg,y.png,z.gif;a.jpg,b.png,c.gif", CriticalImagesString());
  CheckDefaultBeaconSupport(finder_->SupportInterval());
}

TEST_F(BeaconCriticalImagesFinderTest, DontRebeaconBeforeTimeout) {
  Beacon();
  // Now simulate a beacon insertion attempt without timing out.
  WriteBackAndResetDriver();
  factory()->mock_timer()->AdvanceMs(options()->beacon_reinstrument_time_sec() *
                                     Timer::kSecondMs / 2);
  BeaconMetadata metadata =
      finder_->PrepareForBeaconInsertion(rewrite_driver());
  EXPECT_EQ(kDoNotBeacon, metadata.status);
  // But we'll re-beacon if some more time passes.
  Beacon();  // beacon_reinstrument_time_sec() passes in Beacon() call.
}

TEST_F(BeaconCriticalImagesFinderTest, RebeaconBeforeTimeoutWithHeader) {
  Beacon();

  // Write a dummy value to the property cache.
  WriteToPropertyCache();

  // If downstream caching is disabled, any beaconing key configuration and/or
  // presence of PS-ShouldBeacon header should be ignored. In such situations,
  // unless the reinstrumentation time interval is exceeded, beacon injection
  // should not happen.
  ResetDriver();
  SetDownstreamCacheDirectives("", "", kConfiguredBeaconingKey);
  SetShouldBeaconHeader(kConfiguredBeaconingKey);
  VerifyNoBeaconing();
  // Advance the timer past the beacon interval.
  factory()->mock_timer()->AdvanceMs(
      options()->beacon_reinstrument_time_sec() * Timer::kSecondMs + 1);
  // When the reinstrumentation time interval is exceeded, beacon injection
  // should happen as usual.
  ResetDriver();
  SetDownstreamCacheDirectives("", "", kConfiguredBeaconingKey);
  SetShouldBeaconHeader(kConfiguredBeaconingKey);
  VerifyBeaconing();

  // Beacon injection should not happen when rebeaconing key is not configured.
  ResetDriver();
  SetDownstreamCacheDirectives("", "localhost:80", "");
  SetShouldBeaconHeader(kConfiguredBeaconingKey);
  VerifyNoBeaconing();

  // Beacon injection should not happen when the PS-ShouldBeacon header is
  // absent and both downstream caching and the associated rebeaconing key
  // are configured.
  ResetDriver();
  SetDownstreamCacheDirectives("", "localhost:80", kConfiguredBeaconingKey);
  SetDriverRequestHeaders();
  VerifyNoBeaconing();

  // Beacon injection should not happen when the PS-ShouldBeacon header is
  // incorrect.
  ResetDriver();
  SetDownstreamCacheDirectives("", "localhost:80", kConfiguredBeaconingKey);
  SetShouldBeaconHeader(kWrongBeaconingKey);
  VerifyNoBeaconing();

  // Beacon injection happens when the PS-ShouldBeacon header is present even
  // when the pcache value has not expired and the reinstrumentation time
  // interval has not been exceeded.
  ResetDriver();
  SetDownstreamCacheDirectives("", "localhost:80", kConfiguredBeaconingKey);
  SetShouldBeaconHeader(kConfiguredBeaconingKey);
  VerifyBeaconing();

  // Advance the timer past the beacon interval.
  factory()->mock_timer()->AdvanceMs(
      options()->beacon_reinstrument_time_sec() * Timer::kSecondMs + 1);
  // Beacon injection should happen after reinstrumentation time interval has
  // passed when downstream caching is enabled but rebeaconing key is not
  // configured.
  ResetDriver();
  SetDownstreamCacheDirectives("", "localhost:80", "");
  SetShouldBeaconHeader(kConfiguredBeaconingKey);
  VerifyBeaconing();

  // Advance the timer past the beacon interval.
  factory()->mock_timer()->AdvanceMs(
      options()->beacon_reinstrument_time_sec() * Timer::kSecondMs + 1);
  // Beacon injection should not happen when the PS-ShouldBeacon header is
  // incorrect even if the reinstrumentation time interval has been exceeded.
  ResetDriver();
  SetDownstreamCacheDirectives("", "localhost:80", kConfiguredBeaconingKey);
  SetShouldBeaconHeader(kWrongBeaconingKey);
  VerifyNoBeaconing();
}

// Verify that sending enough beacons with the same critical image set puts us
// into low frequency beaconing mode.
TEST_F(BeaconCriticalImagesFinderTest, LowFrequencyBeaconing) {
  StringSet html_critical_images_set;
  html_critical_images_set.insert("x.jpg");
  finder_->UpdateCandidateImagesForBeaconing(
      html_critical_images_set, rewrite_driver(), false /* beaconing */);
  // Send enough beacons to put us into low frequency beaconing mode.
  for (int i = 0; i <= kHighFreqBeaconCount; ++i) {
    Beacon();
    BeaconCriticalImagesFinder::UpdateCriticalImagesCacheEntry(
        &html_critical_images_set, NULL, NULL, last_beacon_metadata_.nonce,
        server_context()->beacon_cohort(), rewrite_driver()->property_page(),
        factory()->mock_timer());
    CriticalKeys* html_critical_images =
        GetCriticalImages()->mutable_html_critical_image_support();
    EXPECT_THAT(html_critical_images->valid_beacons_received(), Eq(i + 1));
  }

  // Now we are in low frequency beaconing mode, so advancing by the high
  // frequency beaconing amount should not trigger beaconing.
  factory()->mock_timer()->AdvanceMs(options()->beacon_reinstrument_time_sec() *
                                     Timer::kSecondMs);
  EXPECT_FALSE(finder_->ShouldBeacon(rewrite_driver()));
  // But advancing by the low frequency amount should.
  factory()->mock_timer()->AdvanceMs(options()->beacon_reinstrument_time_sec() *
                                     Timer::kSecondMs * kLowFreqBeaconMult);
  Beacon();
  factory()->mock_timer()->AdvanceMs(options()->beacon_reinstrument_time_sec() *
                                     Timer::kSecondMs);
  VerifyNoBeaconing();

  // Now verify that updating the candidate images works correctly. If we are
  // beaconing, then the next beacon timestamp does not get updated.
  html_critical_images_set.insert("y.jpg");
  finder_->UpdateCandidateImagesForBeaconing(
      html_critical_images_set, rewrite_driver(), true /* beaconing */);
  VerifyNoBeaconing();

  // Verify that setting the beaconing flag to false when inserting a new
  // candidate key does trigger beaconing on the next request.
  html_critical_images_set.insert("z.jpg");
  finder_->UpdateCandidateImagesForBeaconing(
      html_critical_images_set, rewrite_driver(), false /* beaconing */);
  Beacon();
}

}  // namespace

}  // namespace net_instaweb
