/*
 * 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: marq@google.com (Mark Cogan)

#include "pagespeed/opt/logging/log_record.h"

#include "pagespeed/kernel/base/gtest.h"
#include "pagespeed/kernel/base/null_mutex.h"
#include "pagespeed/kernel/base/scoped_ptr.h"
#include "pagespeed/opt/logging/logging_proto_impl.h"

namespace net_instaweb {

class LogRecordTest : public testing::Test {
 protected:
  virtual void SetUp() {
    log_record_.reset(new LogRecord(new NullMutex));
  }

  // Test that the rewriter_info array is |size| elements long, and that the
  // last element has the |last_id| id string and the |last_status| status.
  void TestRewriterInfo(int size, GoogleString last_id, int last_status) {
    LoggingInfo* l = log_record_->logging_info();
    EXPECT_EQ(size, l->rewriter_info_size());
    EXPECT_EQ(last_id, l->rewriter_info(size-1).id());
    EXPECT_EQ(last_status, l->rewriter_info(size-1).status());
  }

  scoped_ptr<AbstractLogRecord> log_record_;
};

typedef LogRecordTest LogRecordDeathTest;

TEST_F(LogRecordTest, NoAppliedRewriters) {
  LoggingInfo* logging_info = log_record_->logging_info();
  EXPECT_EQ("", log_record_->AppliedRewritersString());
  EXPECT_EQ(0, logging_info->rewriter_info_size());
}

TEST_F(LogRecordTest, SimpleAppliedRewriters) {
  log_record_->SetRewriterLoggingStatus("zz", RewriterApplication::APPLIED_OK);
  TestRewriterInfo(1, "zz", RewriterApplication::APPLIED_OK);
  log_record_->SetRewriterLoggingStatus("aa", RewriterApplication::APPLIED_OK);
  TestRewriterInfo(2, "aa", RewriterApplication::APPLIED_OK);
  EXPECT_EQ("aa,zz",  log_record_->AppliedRewritersString());
}

TEST_F(LogRecordTest, DuplicateAppliedRewriters) {
  log_record_->SetRewriterLoggingStatus("zz", RewriterApplication::APPLIED_OK);
  TestRewriterInfo(1, "zz", RewriterApplication::APPLIED_OK);
  log_record_->SetRewriterLoggingStatus("aa", RewriterApplication::APPLIED_OK);
  TestRewriterInfo(2, "aa", RewriterApplication::APPLIED_OK);
  log_record_->SetRewriterLoggingStatus("zz", RewriterApplication::APPLIED_OK);
  TestRewriterInfo(3, "zz", RewriterApplication::APPLIED_OK);
  EXPECT_EQ("aa,zz", log_record_->AppliedRewritersString());
}

TEST_F(LogRecordTest, ProgressiveAppliedRewriters) {
  log_record_->SetRewriterLoggingStatus("zz", RewriterApplication::APPLIED_OK);
  EXPECT_EQ("zz", log_record_->AppliedRewritersString());
  TestRewriterInfo(1, "zz", RewriterApplication::APPLIED_OK);
  log_record_->SetRewriterLoggingStatus("aa", RewriterApplication::APPLIED_OK);
  EXPECT_EQ("aa,zz", log_record_->AppliedRewritersString());
  TestRewriterInfo(2, "aa", RewriterApplication::APPLIED_OK);
  log_record_->SetRewriterLoggingStatus("zz", RewriterApplication::APPLIED_OK);
  EXPECT_EQ("aa,zz", log_record_->AppliedRewritersString());
  TestRewriterInfo(3, "zz", RewriterApplication::APPLIED_OK);
  log_record_->SetRewriterLoggingStatus("bb", RewriterApplication::APPLIED_OK);
  EXPECT_EQ("aa,bb,zz", log_record_->AppliedRewritersString());
  TestRewriterInfo(4, "bb", RewriterApplication::APPLIED_OK);
}

TEST_F(LogRecordTest, RewriterInfoSizeLimit) {
  LoggingInfo* logging_info = log_record_->logging_info();
  log_record_->SetRewriterInfoMaxSize(2);
  for (int i = 0; i < 100; ++i) {
    log_record_->SetRewriterLoggingStatus("zz",
                                          RewriterApplication::APPLIED_OK);
  }
  EXPECT_EQ("zz", log_record_->AppliedRewritersString());
  EXPECT_TRUE(logging_info->rewriter_info_size_limit_exceeded());
  TestRewriterInfo(2, "zz", RewriterApplication::APPLIED_OK);
}

TEST_F(LogRecordTest, ProgressiveAppliedRewritersWithStatus) {
  LoggingInfo* logging_info = log_record_->logging_info();
  RewriterInfo* info = log_record_->NewRewriterInfo("zz");
  // Not setting the status has the rewriter not show up.
  EXPECT_EQ("", log_record_->AppliedRewritersString());
  TestRewriterInfo(1, "zz", RewriterApplication::UNKNOWN_STATUS);
  // Set it here and it shows up
  info->set_status(RewriterApplication::APPLIED_OK);
  EXPECT_EQ("zz", log_record_->AppliedRewritersString());
  TestRewriterInfo(1, "zz", RewriterApplication::APPLIED_OK);
  // Leave this unset until later
  RewriterInfo* unset_status_info = log_record_->NewRewriterInfo("cc");
  EXPECT_EQ("zz", log_record_->AppliedRewritersString());
  TestRewriterInfo(2, "cc", RewriterApplication::UNKNOWN_STATUS);
  // Adding through the old method interoperates correctly
  log_record_->SetRewriterLoggingStatus("aa", RewriterApplication::APPLIED_OK);
  EXPECT_EQ("aa,zz", log_record_->AppliedRewritersString());
  TestRewriterInfo(3, "aa", RewriterApplication::APPLIED_OK);
  // Adding a duplicate through the new method doesn't produce a dupe in the
  // string
  info = log_record_->NewRewriterInfo("aa");
  info->set_status(RewriterApplication::APPLIED_OK);
  EXPECT_EQ("aa,zz", log_record_->AppliedRewritersString());
  TestRewriterInfo(4, "aa", RewriterApplication::APPLIED_OK);
  // Changing the entry with unset status to OK adds it
  unset_status_info->set_status(RewriterApplication::APPLIED_OK);
  EXPECT_EQ("aa,cc,zz", log_record_->AppliedRewritersString());
  TestRewriterInfo(4, "aa", RewriterApplication::APPLIED_OK);
  // Check that the 'cc' record added earlier is now APPLIED_OK.
  EXPECT_EQ(RewriterApplication::APPLIED_OK,
            logging_info->rewriter_info(1).status());
}

TEST_F(LogRecordTest, DoNotLogUrlsOrIndices) {
  LoggingInfo* logging_info = log_record_->logging_info();
  log_record_->SetRewriterLoggingStatus("z1", "url",
                                        RewriterApplication::APPLIED_OK);
  EXPECT_EQ(0, logging_info->resource_url_info().url_size());
  EXPECT_FALSE(logging_info->rewriter_info(0).has_rewrite_resource_info());
}


TEST_F(LogRecordTest, LogOnlyUrlIndices) {
  LoggingInfo* logging_info = log_record_->logging_info();
  log_record_->SetLogUrlIndices(true);

  // Url not passed as argument.
  log_record_->SetRewriterLoggingStatus("z", RewriterApplication::APPLIED_OK);
  EXPECT_EQ(1, logging_info->rewriter_info_size());
  EXPECT_EQ(0, log_record_->logging_info()->resource_url_info().url_size());
  EXPECT_FALSE(logging_info->rewriter_info(0).has_rewrite_resource_info());

  // Allow logging  not set.
  log_record_->SetRewriterLoggingStatus("z1", "url",
                                        RewriterApplication::APPLIED_OK);
  EXPECT_EQ(0, logging_info->resource_url_info().url_size());
  EXPECT_TRUE(logging_info->rewriter_info(1).has_rewrite_resource_info());
  EXPECT_EQ(0, logging_info->rewriter_info(1).rewrite_resource_info().
            original_resource_url_index());

  // NOT_APPLIED case.
  log_record_->SetRewriterLoggingStatus("z2", "url",
                                        RewriterApplication::NOT_APPLIED);
  EXPECT_EQ(0, logging_info->resource_url_info().url_size());
  EXPECT_TRUE(logging_info->rewriter_info(2).has_rewrite_resource_info());
  EXPECT_EQ(0, logging_info->rewriter_info(1).rewrite_resource_info().
            original_resource_url_index());
}

TEST_F(LogRecordTest, LogUrls) {
  LoggingInfo* logging_info = log_record_->logging_info();
  log_record_->SetAllowLoggingUrls(true);

  // Allow logging set and url passed.
  log_record_->SetRewriterLoggingStatus("z1", "url",
                                        RewriterApplication::APPLIED_OK);
  EXPECT_EQ(1, logging_info->resource_url_info().url_size());
  EXPECT_EQ("url", logging_info->resource_url_info().url(0));
  EXPECT_EQ(0, logging_info->rewriter_info(0).rewrite_resource_info().
            original_resource_url_index());

  // Another record with same url.
  log_record_->SetRewriterLoggingStatus("z2", "url",
                                        RewriterApplication::APPLIED_OK);
  EXPECT_EQ(1, logging_info->resource_url_info().url_size());
  EXPECT_EQ(0, logging_info->rewriter_info(1).rewrite_resource_info().
            original_resource_url_index());

  // Record with different url
  log_record_->SetRewriterLoggingStatus("z3", "url3",
                                        RewriterApplication::APPLIED_OK);
  EXPECT_EQ(2, logging_info->resource_url_info().url_size());
  EXPECT_EQ(1, logging_info->rewriter_info(2).rewrite_resource_info().
            original_resource_url_index());
  EXPECT_EQ("url3", logging_info->resource_url_info().url(1));
}

TEST_F(LogRecordDeathTest, CommasFail) {
  log_record_->SetRewriterLoggingStatus("z,z", RewriterApplication::APPLIED_OK);
  EXPECT_DEBUG_DEATH(log_record_->AppliedRewritersString(), "comma");
}

TEST_F(LogRecordTest, NumHtmlCriticalImages) {
  EXPECT_FALSE(log_record_->logging_info()->has_num_html_critical_images());
  EXPECT_EQ(-1, log_record_->logging_info()->num_html_critical_images());
  log_record_->SetNumHtmlCriticalImages(3);
  EXPECT_EQ(3, log_record_->logging_info()->num_html_critical_images());
}

TEST_F(LogRecordTest, NumCssCriticalImages) {
  EXPECT_FALSE(log_record_->logging_info()->has_num_css_critical_images());
  EXPECT_EQ(-1, log_record_->logging_info()->num_css_critical_images());
  log_record_->SetNumCssCriticalImages(2);
  EXPECT_EQ(2, log_record_->logging_info()->num_css_critical_images());
}

TEST_F(LogRecordTest, SetCriticalCssInfo) {
  EXPECT_FALSE(log_record_->logging_info()->has_critical_css_info());
  log_record_->SetCriticalCssInfo(11, 22, 33);
  EXPECT_TRUE(log_record_->logging_info()->has_critical_css_info());
  const CriticalCssInfo& info =
      log_record_->logging_info()->critical_css_info();
  EXPECT_EQ(11, info.critical_inlined_bytes());
  EXPECT_EQ(22, info.original_external_bytes());
  EXPECT_EQ(33, info.overhead_bytes());
}

TEST_F(LogRecordTest, LogRewriterApplicationStatus) {
  log_record_->LogRewriterHtmlStatus("aa", RewriterHtmlApplication::ACTIVE);
  log_record_->LogRewriterApplicationStatus("aa",
                                            RewriterApplication::APPLIED_OK);
  log_record_->LogRewriterApplicationStatus("aa",
                                            RewriterApplication::NOT_APPLIED);
  log_record_->LogRewriterApplicationStatus("aa",
                                            RewriterApplication::NOT_APPLIED);

  log_record_->LogRewriterApplicationStatus(
      "bb", RewriterApplication::PROPERTY_NOT_FOUND);

  log_record_->LogRewriterHtmlStatus("cc", RewriterHtmlApplication::ACTIVE);
  log_record_->LogRewriterApplicationStatus("cc",
                                            RewriterApplication::APPLIED_OK);

  log_record_->LogRewriterHtmlStatus("dd", RewriterHtmlApplication::DISABLED);

  log_record_->WriteLog();

  // Verify that logging info has the following contents:
  //  rewriter_stats < id: "aa"
  //    html_status: ACTIVE
  //    status_counts { application_status: 1 count: 1 }
  //    status_counts { application_status: 2 count: 2 } >
  //  rewriter_stats < id: "bb"
  //    html_status: UNKNOWN_STATUS
  //    status_counts { application_status: 3 count: 1 } > "
  //  rewriter_stats < id: "cc"
  //    html_status: ACTIVE
  //    status_counts { application_status: 1 count: 1 } >
  //  rewriter_stats < id: "dd"
  //    html_status: DISABLED >
  const LoggingInfo& logged = *log_record_->logging_info();
  EXPECT_EQ(4, logged.rewriter_stats_size());

  EXPECT_EQ("aa", logged.rewriter_stats(0).id());
  EXPECT_EQ(RewriterHtmlApplication::ACTIVE,
            logged.rewriter_stats(0).html_status());
  ASSERT_EQ(2, logged.rewriter_stats(0).status_counts_size());
  EXPECT_EQ(RewriterApplication::APPLIED_OK,
            logged.rewriter_stats(0).status_counts(0).application_status());
  EXPECT_EQ(1, logged.rewriter_stats(0).status_counts(0).count());
  EXPECT_EQ(RewriterApplication::NOT_APPLIED,
            logged.rewriter_stats(0).status_counts(1).application_status());
  EXPECT_EQ(2, logged.rewriter_stats(0).status_counts(1).count());

  // If any application status count is logged, the filter is considered ACTIVE.
  EXPECT_EQ("bb", logged.rewriter_stats(1).id());
  EXPECT_EQ(RewriterHtmlApplication::ACTIVE,
            logged.rewriter_stats(1).html_status());
  ASSERT_EQ(1, logged.rewriter_stats(1).status_counts_size());
  EXPECT_EQ(RewriterApplication::PROPERTY_NOT_FOUND,
            logged.rewriter_stats(1).status_counts(0).application_status());
  EXPECT_EQ(1, logged.rewriter_stats(1).status_counts(0).count());

  EXPECT_EQ("cc", logged.rewriter_stats(2).id());
  EXPECT_EQ(RewriterHtmlApplication::ACTIVE,
            logged.rewriter_stats(2).html_status());
  ASSERT_EQ(1, logged.rewriter_stats(1).status_counts_size());
  EXPECT_EQ(RewriterApplication::APPLIED_OK,
            logged.rewriter_stats(2).status_counts(0).application_status());
  EXPECT_EQ(1, logged.rewriter_stats(2).status_counts(0).count());

  EXPECT_EQ("dd", logged.rewriter_stats(3).id());
  EXPECT_EQ(RewriterHtmlApplication::DISABLED,
            logged.rewriter_stats(3).html_status());
  ASSERT_EQ(0, logged.rewriter_stats(3).status_counts_size());

  // We do not yet populate the applied rewriters string.
  EXPECT_EQ("", log_record_->AppliedRewritersString());
}

TEST_F(LogRecordTest, LogIsXhr) {
  EXPECT_FALSE(log_record_->logging_info()->has_is_xhr());
  log_record_->LogIsXhr(true);
  EXPECT_TRUE(log_record_->logging_info()->has_is_xhr());
  EXPECT_TRUE(log_record_->logging_info()->is_xhr());
}

}  // namespace net_instaweb
