// Copyright 2016 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 "third_party/blink/renderer/core/html/custom/custom_element_upgrade_sorter.h"

#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/dom/element_traversal.h"
#include "third_party/blink/renderer/core/dom/node.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
#include "third_party/blink/renderer/core/html/html_link_element.h"
#include "third_party/blink/renderer/core/html/imports/html_import_child.h"
#include "third_party/blink/renderer/core/html/imports/html_import_loader.h"

namespace blink {

CustomElementUpgradeSorter::CustomElementUpgradeSorter()
    : elements_(MakeGarbageCollected<HeapHashSet<Member<Element>>>()),
      parent_child_map_(MakeGarbageCollected<ParentChildMap>()) {}

static HTMLLinkElement* GetLinkElementForImport(const Document& import) {
  if (HTMLImportLoader* loader = import.ImportLoader())
    return loader->FirstImport()->Link();
  return nullptr;
}

CustomElementUpgradeSorter::AddResult
CustomElementUpgradeSorter::AddToParentChildMap(Node* parent, Node* child) {
  ParentChildMap::AddResult result = parent_child_map_->insert(parent, nullptr);
  if (!result.is_new_entry) {
    result.stored_value->value->insert(child);
    // The entry for the parent exists; so must its parents.
    return kParentAlreadyExistsInMap;
  }

  ChildSet* child_set = MakeGarbageCollected<ChildSet>();
  child_set->insert(child);
  result.stored_value->value = child_set;
  return kParentAddedToMap;
}

void CustomElementUpgradeSorter::Add(Element* element) {
  elements_->insert(element);

  for (Node *n = element, *parent = n->ParentOrShadowHostNode(); parent;
       n = parent, parent = parent->ParentOrShadowHostNode()) {
    if (AddToParentChildMap(parent, n) == kParentAlreadyExistsInMap)
      break;

    // Create parent-child link between <link rel="import"> and its imported
    // document so that the content of the imported document be visited as if
    // the imported document were inserted in the link element.
    if (auto* document = DynamicTo<Document>(parent)) {
      Element* link = GetLinkElementForImport(*document);
      if (!link ||
          AddToParentChildMap(link, parent) == kParentAlreadyExistsInMap)
        break;
      parent = link;
    }
  }
}

void CustomElementUpgradeSorter::Visit(HeapVector<Member<Element>>* result,
                                       ChildSet& children,
                                       const ChildSet::iterator& it) {
  if (it == children.end())
    return;
  auto* element = DynamicTo<Element>(it->Get());
  if (element && elements_->Contains(element))
    result->push_back(*element);
  Sorted(result, *it);
  children.erase(it);
}

void CustomElementUpgradeSorter::Sorted(HeapVector<Member<Element>>* result,
                                        Node* parent) {
  ParentChildMap::iterator children_iterator = parent_child_map_->find(parent);
  if (children_iterator == parent_child_map_->end())
    return;

  ChildSet* children = children_iterator->value.Get();

  if (children->size() == 1) {
    Visit(result, *children, children->begin());
    return;
  }

  // TODO(dominicc): When custom elements are used in UA shadow
  // roots, expand this to include UA shadow roots.
  auto* element = DynamicTo<Element>(parent);
  ShadowRoot* shadow_root = element ? element->AuthorShadowRoot() : nullptr;
  if (shadow_root)
    Visit(result, *children, children->find(shadow_root));

  for (Element* e = ElementTraversal::FirstChild(*parent);
       e && children->size() > 1; e = ElementTraversal::NextSibling(*e)) {
    Visit(result, *children, children->find(e));
  }

  if (children->size() == 1)
    Visit(result, *children, children->begin());

  DCHECK(children->IsEmpty());
}

}  // namespace blink
