/*
 * Copyright 2011 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: jmarantz@google.com (Joshua Marantz)

#include <memory>

#include "net/instaweb/rewriter/public/common_filter.h"
#include "net/instaweb/rewriter/public/flush_html_filter.h"
#include "net/instaweb/rewriter/public/resource_tag_scanner.h"
#include "net/instaweb/rewriter/public/rewrite_driver.h"
#include "pagespeed/kernel/http/semantic_type.h"

namespace {

// Controls the number of resource references that will be scanned before a
// Flush is issued.
//
// TODO(jmarantz): Make these configurable via RewriteOptions.
// TODO(jmarantz): Consider gaps in realtime as justification to induce flushes
// as well.  That might be beyond the scope of this filter.
const int kFlushScoreThreshold = 80;
const int kFlushCssScore = 10;     // 8 CSS files induces a flush.
const int kFlushScriptScore = 10;  // 8 Scripts files induces a flush.
const int kFlushImageScore = 2;    // 40 images induces a flush.

}  // namespace

namespace net_instaweb {

class HtmlElement;

FlushHtmlFilter::FlushHtmlFilter(RewriteDriver* driver)
    : CommonFilter(driver),
      score_(0) {
}

FlushHtmlFilter::~FlushHtmlFilter() {}

void FlushHtmlFilter::StartDocumentImpl() {
  score_ = 0;
}

void FlushHtmlFilter::Flush() {
  score_ = 0;
}

void FlushHtmlFilter::StartElementImpl(HtmlElement* element) {
  resource_tag_scanner::UrlCategoryVector attributes;
  resource_tag_scanner::ScanElement(element, driver()->options(), &attributes);
  for (int i = 0, n = attributes.size(); i < n; ++i) {
    switch (attributes[i].category) {
      case semantic_type::kStylesheet:
        score_ += kFlushCssScore;
        break;
      case semantic_type::kScript:
        score_ += kFlushScriptScore;
        break;
      case semantic_type::kImage:
        score_ += kFlushImageScore;
        break;
      default:
        break;
    }
  }
}

void FlushHtmlFilter::EndElementImpl(HtmlElement* element) {
  resource_tag_scanner::UrlCategoryVector attributes;
  resource_tag_scanner::ScanElement(element, driver()->options(), &attributes);
  if (!attributes.empty() && score_ >= kFlushScoreThreshold) {
    score_ = 0;
    driver()->RequestFlush();
  }
}

}  // namespace net_instaweb
