/*
 * 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: abliss@google.com (Adam Bliss)

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

#include "base/logging.h"
#include "net/instaweb/http/public/request_context.h"
#include "net/instaweb/http/public/request_timing_info.h"
#include "net/instaweb/rewriter/public/experiment_util.h"
#include "net/instaweb/rewriter/public/request_properties.h"
#include "net/instaweb/rewriter/public/rewrite_driver.h"
#include "net/instaweb/rewriter/public/rewrite_options.h"
#include "net/instaweb/rewriter/public/server_context.h"
#include "net/instaweb/rewriter/public/static_asset_manager.h"
#include "pagespeed/kernel/base/escaping.h"
#include "pagespeed/kernel/base/ref_counted_ptr.h"
#include "pagespeed/kernel/base/statistics.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/base/string_util.h"
#include "pagespeed/kernel/html/html_element.h"
#include "pagespeed/kernel/html/html_name.h"
#include "pagespeed/kernel/html/html_node.h"
#include "pagespeed/kernel/http/google_url.h"
#include "pagespeed/kernel/http/http_names.h"
#include "pagespeed/kernel/http/response_headers.h"

namespace net_instaweb {

namespace {

// The javascript tag to insert in the top of the <head> element.  We want this
// as early as possible in the html.  It must be short and fast.
const char kHeadScript[] =
    "<script type='text/javascript'>"
    "window.mod_pagespeed_start = Number(new Date());"
    "</script>";

}  // namespace

// Timing tag for total page load time.  Also embedded in kTailScriptFormat
// above via the second %s.
// TODO(jud): These values would be better set to "load" and "beforeunload".
const char AddInstrumentationFilter::kLoadTag[] = "load:";
const char AddInstrumentationFilter::kUnloadTag[] = "unload:";

// Counters.
const char AddInstrumentationFilter::kInstrumentationScriptAddedCount[] =
    "instrumentation_filter_script_added_count";
AddInstrumentationFilter::AddInstrumentationFilter(RewriteDriver* driver)
    : CommonFilter(driver),
      found_head_(false),
      added_head_script_(false),
      added_unload_script_(false) {
  Statistics* stats = driver->server_context()->statistics();
  instrumentation_script_added_count_ = stats->GetVariable(
      kInstrumentationScriptAddedCount);
}

AddInstrumentationFilter::~AddInstrumentationFilter() {}

void AddInstrumentationFilter::InitStats(Statistics* statistics) {
  statistics->AddVariable(kInstrumentationScriptAddedCount);
}

void AddInstrumentationFilter::StartDocumentImpl() {
  found_head_ = false;
  added_head_script_ = false;
  added_unload_script_ = false;
}

void AddInstrumentationFilter::AddHeadScript(HtmlElement* element) {
  // IE doesn't like tags other than title or meta at the start of the
  // head. The MSDN page says:
  //   The X-UA-Compatible header isn't case sensitive; however, it must appear
  //   in the header of the webpage (the HEAD section) before all other elements
  //   except for the title element and other meta elements.
  // Reference: http://msdn.microsoft.com/en-us/library/jj676915(v=vs.85).aspx
  if (element->keyword() != HtmlName::kTitle &&
      element->keyword() != HtmlName::kMeta) {
    added_head_script_ = true;
    // TODO(abliss): add an actual element instead, so other filters can
    // rewrite this JS
    HtmlCharactersNode* script = driver()->NewCharactersNode(NULL, kHeadScript);
    driver()->InsertNodeBeforeCurrent(script);
    instrumentation_script_added_count_->Add(1);
  }
}

void AddInstrumentationFilter::StartElementImpl(HtmlElement* element) {
  if (found_head_ && !added_head_script_) {
    AddHeadScript(element);
  }
  if (!found_head_ && element->keyword() == HtmlName::kHead) {
    found_head_ = true;
  }
}

void AddInstrumentationFilter::EndElementImpl(HtmlElement* element) {
  if (found_head_ && element->keyword() == HtmlName::kHead) {
    if (!added_head_script_) {
      AddHeadScript(element);
    }
    if (driver()->options()->report_unload_time() &&
        !added_unload_script_) {
      GoogleString js = GetScriptJs(kUnloadTag);
      HtmlElement* script = driver()->NewElement(element, HtmlName::kScript);
      if (!driver()->defer_instrumentation_script()) {
        driver()->AddAttribute(script, HtmlName::kDataPagespeedNoDefer, NULL);
      }
      driver()->InsertNodeBeforeCurrent(script);
      AddJsToElement(js, script);
      added_unload_script_ = true;
    }
  }
}

void AddInstrumentationFilter::EndDocument() {
  // We relied on the existence of a <head> element.  This should have been
  // assured by add_head_filter.
  if (!found_head_) {
    LOG(WARNING) << "No <head> found for URL " << driver()->url();
    return;
  }
  GoogleString js = GetScriptJs(kLoadTag);
  HtmlElement* script = driver()->NewElement(NULL, HtmlName::kScript);
  if (!driver()->defer_instrumentation_script()) {
    driver()->AddAttribute(script, HtmlName::kDataPagespeedNoDefer, NULL);
  }
  InsertNodeAtBodyEnd(script);
  AddJsToElement(js, script);
}

GoogleString AddInstrumentationFilter::GetScriptJs(StringPiece event) {
  GoogleString js;
  StaticAssetManager* static_asset_manager =
      driver()->server_context()->static_asset_manager();
  // Only add the static JS once.
  if (!added_unload_script_) {
    if (driver()->options()->enable_extended_instrumentation()) {
      js = static_asset_manager->GetAsset(
          StaticAssetEnum::EXTENDED_INSTRUMENTATION_JS, driver()->options());
    }
    StrAppend(&js, static_asset_manager->GetAsset(
        StaticAssetEnum::ADD_INSTRUMENTATION_JS, driver()->options()));
  }

  GoogleString js_event = (event == kLoadTag) ? "load" : "beforeunload";

  const RewriteOptions::BeaconUrl& beacons = driver()->options()->beacon_url();
  const GoogleString* beacon_url =
      driver()->IsHttps() ? &beacons.https : &beacons.http;
  GoogleString extra_params;
  if (driver()->options()->running_experiment()) {
    int experiment_state = driver()->options()->experiment_id();
    if (experiment_state != experiment::kExperimentNotSet &&
        experiment_state != experiment::kNoExperiment) {
      StrAppend(&extra_params, "&exptid=",
                IntegerToString(driver()->options()->experiment_id()));
    }
  }

  const RequestTimingInfo& timing_info =
      driver()->request_context()->timing_info();
  int64 header_fetch_ms;
  if (timing_info.GetFetchHeaderLatencyMs(&header_fetch_ms)) {
    // If time taken to fetch the http header is not set, then the response
    // came from cache.
    StrAppend(&extra_params, "&hft=", Integer64ToString(header_fetch_ms));
  }
  int64 fetch_ms;
  if (timing_info.GetFetchLatencyMs(&fetch_ms)) {
    // If time taken to fetch the resource is not set, then the response
    // came from cache.
    StrAppend(&extra_params, "&ft=", Integer64ToString(fetch_ms));
  }
  int64 ttfb_ms;
  if (timing_info.GetTimeToFirstByte(&ttfb_ms)) {
    StrAppend(&extra_params, "&s_ttfb=", Integer64ToString(ttfb_ms));
  }

  // Append the http response code.
  if (driver()->response_headers() != NULL &&
      driver()->response_headers()->status_code() > 0 &&
      driver()->response_headers()->status_code() != HttpStatus::kOK) {
    StrAppend(&extra_params, "&rc=", IntegerToString(
        driver()->response_headers()->status_code()));
  }
  // Append the request id.
  if (driver()->request_context()->request_id() > 0) {
    StrAppend(&extra_params, "&id=", Integer64ToString(
        driver()->request_context()->request_id()));
  }

  GoogleString html_url;
  EscapeToJsStringLiteral(driver()->google_url().Spec(),
                          false, /* no quotes */
                          &html_url);

  StrAppend(&js, "\npagespeed.addInstrumentationInit(");
  StrAppend(&js, "'", *beacon_url, "', ");
  StrAppend(&js, "'", js_event, "', ");
  StrAppend(&js, "'", extra_params, "', ");
  StrAppend(&js, "'", html_url, "');");

  return js;
}

void AddInstrumentationFilter::DetermineEnabled(GoogleString* disabled_reason) {
  set_is_enabled(!driver()->request_properties()->IsBot());
}

}  // namespace net_instaweb
