// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "extensions/renderer/content_watcher.h"

#include <stddef.h>

#include <set>

#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_frame_observer.h"
#include "content/public/renderer/render_frame_observer_tracker.h"
#include "content/public/renderer/render_frame_visitor.h"
#include "content/public/renderer/render_view.h"
#include "extensions/common/extension_messages.h"
#include "third_party/blink/public/web/web_document.h"
#include "third_party/blink/public/web/web_element.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/blink/public/web/web_view.h"

namespace extensions {

namespace {

class FrameContentWatcher
    : public content::RenderFrameObserver,
      public content::RenderFrameObserverTracker<FrameContentWatcher> {
 public:
  FrameContentWatcher(content::RenderFrame* render_frame,
                      const blink::WebVector<blink::WebString>& css_selectors);
  ~FrameContentWatcher() override;

  // content::RenderFrameObserver:
  void OnDestruct() override;
  void DidCreateDocumentElement() override;
  void DidMatchCSS(
      const blink::WebVector<blink::WebString>& newly_matching_selectors,
      const blink::WebVector<blink::WebString>& stopped_matching_selectors)
      override;

  void UpdateCSSSelectors(const blink::WebVector<blink::WebString>& selectors);

 private:
  // Given that we saw a change in the CSS selectors that the associated frame
  // matched, tells the browser about the new set of matching selectors in its
  // top-level page. We filter this so that if an extension were to be granted
  // activeTab permission on that top-level page, we only send CSS selectors for
  // frames that it could run on.
  // Note: Currently, this works with OOPIFs because, since we only send this
  // for a matching selector found in a frame that the top frame can access,
  // that frame is guaranteed to be local. If we ever isolate frames regardless
  // of whether the top frame could access them, or if we notify of matches for
  // frames the top frame cannot access, we may have to rethink this.
  void NotifyBrowserOfChange();

  blink::WebVector<blink::WebString> css_selectors_;
  std::set<std::string> matching_selectors_;
  bool document_created_ = false;

  DISALLOW_COPY_AND_ASSIGN(FrameContentWatcher);
};

FrameContentWatcher::FrameContentWatcher(
    content::RenderFrame* render_frame,
    const blink::WebVector<blink::WebString>& css_selectors)
    : content::RenderFrameObserver(render_frame),
      content::RenderFrameObserverTracker<FrameContentWatcher>(render_frame),
      css_selectors_(css_selectors) {}

FrameContentWatcher::~FrameContentWatcher() {}

void FrameContentWatcher::OnDestruct() {
  delete this;
}

void FrameContentWatcher::DidCreateDocumentElement() {
  document_created_ = true;
  render_frame()->GetWebFrame()->GetDocument().WatchCSSSelectors(
      css_selectors_);
}

void FrameContentWatcher::DidMatchCSS(
    const blink::WebVector<blink::WebString>& newly_matching_selectors,
    const blink::WebVector<blink::WebString>& stopped_matching_selectors) {
  for (size_t i = 0; i < stopped_matching_selectors.size(); ++i)
    matching_selectors_.erase(stopped_matching_selectors[i].Utf8());
  for (size_t i = 0; i < newly_matching_selectors.size(); ++i)
    matching_selectors_.insert(newly_matching_selectors[i].Utf8());

  NotifyBrowserOfChange();
}

void FrameContentWatcher::UpdateCSSSelectors(
    const blink::WebVector<blink::WebString>& selectors) {
  css_selectors_ = selectors;
  if (document_created_) {
    render_frame()->GetWebFrame()->GetDocument().WatchCSSSelectors(
        css_selectors_);
  }
}

void FrameContentWatcher::NotifyBrowserOfChange() {
  blink::WebLocalFrame* changed_frame = render_frame()->GetWebFrame();
  blink::WebFrame* const top_frame = changed_frame->Top();
  const blink::WebSecurityOrigin top_origin = top_frame->GetSecurityOrigin();
  // Want to aggregate matched selectors from all frames where an
  // extension with access to top_origin could run on the frame.
  if (!top_origin.CanAccess(changed_frame->GetSecurityOrigin())) {
    // If the changed frame can't be accessed by the top frame, then
    // no change in it could affect the set of selectors we'd send back.
    return;
  }

  std::set<base::StringPiece> transitive_selectors;
  for (blink::WebFrame* frame = top_frame; frame;
       frame = frame->TraverseNext()) {
    if (frame->IsWebLocalFrame() &&
        top_origin.CanAccess(frame->GetSecurityOrigin())) {
      FrameContentWatcher* watcher = FrameContentWatcher::Get(
          content::RenderFrame::FromWebFrame(frame->ToWebLocalFrame()));
      if (watcher && !watcher->matching_selectors_.empty()) {
        transitive_selectors.insert(watcher->matching_selectors_.begin(),
                                    watcher->matching_selectors_.end());
      }
    }
  }

  std::vector<std::string> selector_strings;
  for (const base::StringPiece& selector : transitive_selectors)
    selector_strings.push_back(selector.as_string());

  // TODO(devlin): Frame-ify this message.
  content::RenderView* view =
      content::RenderView::FromWebView(top_frame->View());
  view->Send(new ExtensionHostMsg_OnWatchedPageChange(view->GetRoutingID(),
                                                      selector_strings));
}

}  // namespace

ContentWatcher::ContentWatcher() {}
ContentWatcher::~ContentWatcher() {}

void ContentWatcher::OnWatchPages(
    const std::vector<std::string>& new_css_selectors_utf8) {
  blink::WebVector<blink::WebString> new_css_selectors(
      new_css_selectors_utf8.size());
  bool changed = new_css_selectors.size() != css_selectors_.size();
  for (size_t i = 0; i < new_css_selectors.size(); ++i) {
    new_css_selectors[i] =
        blink::WebString::FromUTF8(new_css_selectors_utf8[i]);
    if (!changed && new_css_selectors[i] != css_selectors_[i])
      changed = true;
  }

  if (!changed)
    return;

  css_selectors_.Swap(new_css_selectors);

  // Tell each frame's document about the new set of watched selectors. These
  // will trigger calls to DidMatchCSS after Blink has a chance to apply the new
  // style, which will in turn notify the browser about the changes.
  struct WatchSelectors : public content::RenderFrameVisitor {
    explicit WatchSelectors(
        const blink::WebVector<blink::WebString>& css_selectors)
        : css_selectors(css_selectors) {}

    bool Visit(content::RenderFrame* frame) override {
      FrameContentWatcher::Get(frame)->UpdateCSSSelectors(css_selectors);
      return true;  // Continue visiting.
    }

    const blink::WebVector<blink::WebString>& css_selectors;
  };
  WatchSelectors visitor(css_selectors_);
  content::RenderFrame::ForEach(&visitor);
}

void ContentWatcher::OnRenderFrameCreated(content::RenderFrame* render_frame) {
  // Manages its own lifetime.
  new FrameContentWatcher(render_frame, css_selectors_);
}

}  // namespace extensions
