// Copyright 2017 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 "core/exported/WebFormElementObserverImpl.h"

#include "core/css/CSSComputedStyleDeclaration.h"
#include "core/dom/MutationObserver.h"
#include "core/dom/MutationObserverInit.h"
#include "core/dom/MutationRecord.h"
#include "core/dom/StaticNodeList.h"
#include "core/html/HTMLElement.h"
#include "core/html/forms/HTMLFormElement.h"
#include "core/html/forms/HTMLInputElement.h"
#include "public/web/WebFormElement.h"
#include "public/web/WebInputElement.h"
#include "public/web/modules/password_manager/WebFormElementObserverCallback.h"

namespace blink {

class WebFormElementObserverImpl::ObserverCallback
    : public MutationObserver::Delegate {
 public:
  ObserverCallback(HTMLElement&,
                   std::unique_ptr<WebFormElementObserverCallback>);

  ExecutionContext* GetExecutionContext() const override;

  void Deliver(const MutationRecordVector& records, MutationObserver&) override;

  void Disconnect();

  virtual void Trace(blink::Visitor*);

 private:
  Member<HTMLElement> element_;
  Member<MutationObserver> mutation_observer_;
  std::unique_ptr<WebFormElementObserverCallback> callback_;
};

WebFormElementObserverImpl::ObserverCallback::ObserverCallback(
    HTMLElement& element,
    std::unique_ptr<WebFormElementObserverCallback> callback)
    : element_(element),
      mutation_observer_(MutationObserver::Create(this)),
      callback_(std::move(callback)) {
  {
    MutationObserverInit init;
    init.setAttributes(true);
    init.setAttributeFilter({"action", "class", "style"});
    mutation_observer_->observe(element_, init, ASSERT_NO_EXCEPTION);
  }
  if (element_->parentElement()) {
    MutationObserverInit init;
    init.setChildList(true);
    mutation_observer_->observe(element_->parentElement(), init,
                                ASSERT_NO_EXCEPTION);
  }
}

ExecutionContext*
WebFormElementObserverImpl::ObserverCallback::GetExecutionContext() const {
  return &element_->GetDocument();
}

void WebFormElementObserverImpl::ObserverCallback::Deliver(
    const MutationRecordVector& records,
    MutationObserver&) {
  for (const auto& record : records) {
    if (record->type() == "childList") {
      for (unsigned i = 0; i < record->removedNodes()->length(); ++i) {
        if (record->removedNodes()->item(i) != element_)
          continue;
        callback_->ElementWasHiddenOrRemoved();
        Disconnect();
        return;
      }
    } else {
      HTMLElement& element = *ToHTMLElement(record->target());
      if (record->attributeName() == "action") {
        // If the action was modified, we just assume that the form as
        // submitted.
        callback_->ElementWasHiddenOrRemoved();
        Disconnect();
        return;
      }
      // Otherwise, either "style" or "class" was modified. Check the
      // computed style.
      CSSComputedStyleDeclaration* style =
          CSSComputedStyleDeclaration::Create(&element);
      if (style->GetPropertyValue(CSSPropertyDisplay) == "none") {
        callback_->ElementWasHiddenOrRemoved();
        Disconnect();
        return;
      }
    }
  }
}

void WebFormElementObserverImpl::ObserverCallback::Disconnect() {
  mutation_observer_->disconnect();
  callback_.reset();
}

void WebFormElementObserverImpl::ObserverCallback::Trace(
    blink::Visitor* visitor) {
  visitor->Trace(element_);
  visitor->Trace(mutation_observer_);
  MutationObserver::Delegate::Trace(visitor);
}

WebFormElementObserver* WebFormElementObserver::Create(
    WebFormElement& element,
    std::unique_ptr<WebFormElementObserverCallback> callback) {
  return new WebFormElementObserverImpl(*element.Unwrap<HTMLFormElement>(),
                                        std::move(callback));
}

WebFormElementObserver* WebFormElementObserver::Create(
    WebInputElement& element,
    std::unique_ptr<WebFormElementObserverCallback> callback) {
  return new WebFormElementObserverImpl(*element.Unwrap<HTMLInputElement>(),
                                        std::move(callback));
}

WebFormElementObserverImpl::WebFormElementObserverImpl(
    HTMLElement& element,
    std::unique_ptr<WebFormElementObserverCallback> callback)
    : self_keep_alive_(this) {
  mutation_callback_ = new ObserverCallback(element, std::move(callback));
}

WebFormElementObserverImpl::~WebFormElementObserverImpl() = default;

void WebFormElementObserverImpl::Disconnect() {
  mutation_callback_->Disconnect();
  mutation_callback_ = nullptr;
  self_keep_alive_.Clear();
}

void WebFormElementObserverImpl::Trace(blink::Visitor* visitor) {
  visitor->Trace(mutation_callback_);
}

}  // namespace blink
