/*
 * 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: sligocki@google.com (Shawn Ligocki)

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

#include "net/instaweb/rewriter/public/output_resource.h"
#include "net/instaweb/rewriter/public/output_resource_kind.h"
#include "net/instaweb/rewriter/public/resource.h"
#include "net/instaweb/rewriter/public/rewrite_driver.h"
#include "net/instaweb/rewriter/public/rewrite_options.h"
#include "net/instaweb/rewriter/public/script_tag_scanner.h"
#include "net/instaweb/rewriter/public/server_context.h"
#include "pagespeed/kernel/base/ref_counted_ptr.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/content_type.h"

namespace net_instaweb {

class MessageHandler;

const char JsOutlineFilter::kFilterId[] = "jo";

JsOutlineFilter::JsOutlineFilter(RewriteDriver* driver)
    : CommonFilter(driver),
      inline_element_(NULL),
      inline_chars_(NULL),
      server_context_(driver->server_context()),
      size_threshold_bytes_(driver->options()->js_outline_min_bytes()),
      script_tag_scanner_(driver) { }

JsOutlineFilter::~JsOutlineFilter() {}

void JsOutlineFilter::StartDocumentImpl() {
  inline_element_ = NULL;
  inline_chars_ = NULL;
}

void JsOutlineFilter::StartElementImpl(HtmlElement* element) {
  // No tags allowed inside script element.
  if (inline_element_ != NULL) {
    // TODO(sligocki): Add negative unit tests to hit these errors.
    driver()->ErrorHere("Tag '%s' found inside script.",
                        CEscape(element->name_str()).c_str());
    inline_element_ = NULL;  // Don't outline what we don't understand.
    inline_chars_ = NULL;
  }

  HtmlElement::Attribute* src;
  // We only deal with Javascript
  if (script_tag_scanner_.ParseScriptElement(element, &src) ==
      ScriptTagScanner::kJavaScript) {
    inline_element_ = element;
    inline_chars_ = NULL;
    // script elements which already have a src should not be outlined.
    if (src != NULL) {
      inline_element_ = NULL;
    }
  }
}

void JsOutlineFilter::EndElementImpl(HtmlElement* element) {
  if (inline_element_ != NULL) {
    if (element != inline_element_) {
      // No other tags allowed inside script element.
      driver()->ErrorHere("Tag '%s' found inside script.",
                          CEscape(element->name_str()).c_str());
    } else if (inline_chars_ != NULL &&
               inline_chars_->contents().size() >= size_threshold_bytes_) {
      OutlineScript(inline_element_, inline_chars_->contents());
    }
    inline_element_ = NULL;
    inline_chars_ = NULL;
  }
}

void JsOutlineFilter::Flush() {
  // If we were flushed in a script element, we cannot outline it.
  inline_element_ = NULL;
  inline_chars_ = NULL;
}

void JsOutlineFilter::Characters(HtmlCharactersNode* characters) {
  if (inline_element_ != NULL) {
    inline_chars_ = characters;
  }
}

// Try to write content and possibly header to resource.
bool JsOutlineFilter::WriteResource(const GoogleString& content,
                                    OutputResource* resource,
                                    MessageHandler* handler) {
  // We don't provide charset here since in generally we can just inherit
  // from the page.
  // TODO(morlovich) check for proper behavior in case of embedded BOM.
  return driver()->Write(
      ResourceVector(), content, &kContentTypeJavascript, StringPiece(),
      resource);
}

// Create file with script content and remove that element from DOM.
void JsOutlineFilter::OutlineScript(HtmlElement* inline_element,
                                    const GoogleString& content) {
  if (driver()->IsRewritable(inline_element)) {
    // Create script file from content.
    MessageHandler* handler = driver()->message_handler();
    // Create outline resource at the document location, not base URL location
    GoogleString failure_reason;
    OutputResourcePtr resource(
        driver()->CreateOutputResourceWithUnmappedUrl(
            driver()->google_url(), kFilterId, "_", kOutlinedResource,
            &failure_reason));
    if (resource.get() == NULL) {
      driver()->InsertDebugComment(failure_reason, inline_element);
    } else if (WriteResource(content, resource.get(), handler)) {
      HtmlElement* outline_element = driver()->CloneElement(inline_element);
      driver()->AddAttribute(outline_element, HtmlName::kSrc,
                             resource->url());
      // Add <script src=...> element to DOM.
      driver()->InsertNodeBeforeNode(inline_element, outline_element);
      // Remove original script element from DOM.
      if (!driver()->DeleteNode(inline_element)) {
        driver()->FatalErrorHere("Failed to delete inline script element");
      }
    } else {
      driver()->InsertDebugComment("Failed to write outlined script resource.",
                                   inline_element);
      driver()->ErrorHere("Failed to write outlined script resource.");
    }
  }
}

}  // namespace net_instaweb
