/*
 * 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: slamm@google.com (Stephen Lamm),
//         morlovich@google.com (Maksim Orlovich)
//
// This filters helps inline a subset of CSS critical to initial rendering of
// the webpage by focusing only on declarations whose selectors match
// elements critical to such rendering. The full original CSS is moved to the
// foot of the webpage and lazy-loaded via JS.

#ifndef NET_INSTAWEB_REWRITER_PUBLIC_CRITICAL_SELECTOR_FILTER_H_
#define NET_INSTAWEB_REWRITER_PUBLIC_CRITICAL_SELECTOR_FILTER_H_

#include <vector>

#include "net/instaweb/rewriter/public/css_summarizer_base.h"
#include "net/instaweb/rewriter/public/rewrite_driver.h"
#include "net/instaweb/rewriter/public/rewrite_options.h"
#include "pagespeed/kernel/base/basictypes.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/base/string_util.h"
#include "pagespeed/kernel/http/semantic_type.h"

namespace Css {

class Stylesheet;

}  // namespace Css

namespace net_instaweb {

class HtmlCharactersNode;
class HtmlElement;

class CriticalSelectorFilter : public CssSummarizerBase {
 public:
  static const char kAddStylesFunction[];
  static const char kAddStylesInvocation[];
  static const char kApplyFlushEarlyCss[];
  static const char kInvokeFlushEarlyCssTemplate[];
  static const char kMoveScriptId[];
  static const char kNoscriptStylesClass[];

  explicit CriticalSelectorFilter(RewriteDriver* rewrite_driver);
  virtual ~CriticalSelectorFilter();

  virtual const char* Name() const { return "CriticalSelectorFilter"; }
  virtual const char* id() const { return "cl"; }

  // This filter needs access to all critical selectors (even those from
  // unauthorized domains) in order to inline them into HTML.
  // Inlining css from unauthorized domains into HTML is considered
  // safe because it does not cause any new content to be executed compared
  // to the unoptimized page.
  virtual RewriteDriver::InlineAuthorizationPolicy AllowUnauthorizedDomain()
      const {
    return driver()->options()->HasInlineUnauthorizedResourceType(
               semantic_type::kStylesheet) ?
           RewriteDriver::kInlineUnauthorizedResources :
           RewriteDriver::kInlineOnlyAuthorizedResources;
  }

  // Selectors are inlined into the html.
  virtual bool IntendedForInlining() const { return true; }

 protected:
  // Overrides of CssSummarizerBase summary API. These help us compute
  // the critical portions of the various fragments in the page, and to
  // write them out to the page. We also use this to pick up the output
  // of filters before us, like rewrite_css; so we run this even on things
  // that will not contain on-screen critical CSS.
  virtual void Summarize(Css::Stylesheet* stylesheet,
                         GoogleString* out) const;
  virtual void RenderSummary(int pos,
                             HtmlElement* element,
                             HtmlCharactersNode* char_node,
                             bool* is_element_deleted);
  virtual void WillNotRenderSummary(int pos,
                                    HtmlElement* element,
                                    HtmlCharactersNode* char_node,
                                    bool* is_element_deleted);

  // Since our computation depends on the selectors that are relevant to the
  // webpage, we incorporate them into the cache key as well.
  virtual GoogleString CacheKeySuffix() const;

  // Parser callbacks.
  virtual void StartDocumentImpl();
  virtual void EndDocument();
  virtual void RenderDone();

  // Filter control API.
  virtual void DetermineEnabled(GoogleString* disabled_reason);

 private:
  class CssElement;
  class CssStyleElement;
  typedef std::vector<CssElement*> CssElementVector;

  void RememberFullCss(int pos,
                       HtmlElement* element,
                       HtmlCharactersNode* char_node);

  bool IsCssFlushedEarly(const GoogleString& url) const;
  void ApplyCssFlushedEarly(HtmlElement* element,
                            const GoogleString& style_id,
                            const char* media);

  // Selectors that are critical for this page.
  // These are just copied over from the finder and turned into a set for easier
  // membership checking.
  StringSet critical_selectors_;

  // Summary of critical_selectors_ as a short string.
  GoogleString cache_key_suffix_;

  // Info on all the CSS in the page, potentially as optimized by other filters.
  // We will emit code to lazy-load it at the very end of the document.
  // May contain NULL pointers.
  CssElementVector css_elements_;

  // True if EndDocument was called; helps us identify last flush window.
  bool saw_end_document_;

  // True if we rendered any block at all.
  bool any_rendered_;

  // True if flush early script to move links has been added.
  bool is_flush_script_added_;

  DISALLOW_COPY_AND_ASSIGN(CriticalSelectorFilter);
};

}  // namespace net_instaweb

#endif  // NET_INSTAWEB_REWRITER_PUBLIC_CRITICAL_SELECTOR_FILTER_H_
