// Copyright 2015 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 "components/bubble/bubble_manager.h"

#include <utility>
#include <vector>

#include "components/bubble/bubble_controller.h"
#include "components/bubble/bubble_delegate.h"

BubbleManager::BubbleManager() : manager_state_(SHOW_BUBBLES) {}

BubbleManager::~BubbleManager() {
  FinalizePendingRequests();
}

BubbleReference BubbleManager::ShowBubble(
    std::unique_ptr<BubbleDelegate> bubble) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK_NE(manager_state_, ITERATING_BUBBLES);
  DCHECK(bubble);

  std::unique_ptr<BubbleController> controller(
      new BubbleController(this, std::move(bubble)));

  BubbleReference bubble_ref = controller->AsWeakPtr();

  switch (manager_state_) {
    case SHOW_BUBBLES:
      controller->Show();
      controllers_.push_back(std::move(controller));
      break;
    case NO_MORE_BUBBLES:
      for (auto& observer : observers_)
        observer.OnBubbleNeverShown(controller->AsWeakPtr());
      break;
    default:
      NOTREACHED();
      break;
  }

  return bubble_ref;
}

bool BubbleManager::CloseBubble(BubbleReference bubble,
                                BubbleCloseReason reason) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK_NE(manager_state_, ITERATING_BUBBLES);
  return CloseAllMatchingBubbles(bubble.get(), nullptr, reason);
}

void BubbleManager::CloseAllBubbles(BubbleCloseReason reason) {
  // The following close reasons don't make sense for multiple bubbles:
  DCHECK_NE(reason, BUBBLE_CLOSE_ACCEPTED);
  DCHECK_NE(reason, BUBBLE_CLOSE_CANCELED);
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK_NE(manager_state_, ITERATING_BUBBLES);
  CloseAllMatchingBubbles(nullptr, nullptr, reason);
}

void BubbleManager::UpdateAllBubbleAnchors() {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK_NE(manager_state_, ITERATING_BUBBLES);

  // Guard against bubbles being added or removed while iterating the bubbles.
  ManagerState original_state = manager_state_;
  manager_state_ = ITERATING_BUBBLES;
  for (auto& controller : controllers_)
    controller->UpdateAnchorPosition();
  manager_state_ = original_state;
}

void BubbleManager::AddBubbleManagerObserver(BubbleManagerObserver* observer) {
  observers_.AddObserver(observer);
}

void BubbleManager::RemoveBubbleManagerObserver(
    BubbleManagerObserver* observer) {
  observers_.RemoveObserver(observer);
}

size_t BubbleManager::GetBubbleCountForTesting() const {
  return controllers_.size();
}

void BubbleManager::FinalizePendingRequests() {
  // Return if already "Finalized".
  if (manager_state_ == NO_MORE_BUBBLES)
    return;

  manager_state_ = NO_MORE_BUBBLES;
  CloseAllBubbles(BUBBLE_CLOSE_FORCED);
}

void BubbleManager::CloseBubblesOwnedBy(const content::RenderFrameHost* frame) {
  CloseAllMatchingBubbles(nullptr, frame, BUBBLE_CLOSE_FRAME_DESTROYED);
}

bool BubbleManager::CloseAllMatchingBubbles(
    BubbleController* bubble,
    const content::RenderFrameHost* owner,
    BubbleCloseReason reason) {
  // Specifying both an owning frame and a particular bubble to close doesn't
  // make sense. If we have a frame, all bubbles owned by that frame need to
  // have the opportunity to close. If we want to close a specific bubble, then
  // it should get the close event regardless of which frame owns it. On the
  // other hand, OR'ing the conditions needs a special case in order to be able
  // to close all bubbles, so we disallow passing both until a need appears.
  DCHECK(!bubble || !owner);

  std::vector<std::unique_ptr<BubbleController>> close_queue;

  // Guard against bubbles being added or removed while iterating the bubbles.
  ManagerState original_state = manager_state_;
  manager_state_ = ITERATING_BUBBLES;
  for (auto i = controllers_.begin(); i != controllers_.end();) {
    if ((!bubble || bubble == (*i).get()) &&
        (!owner || (*i)->OwningFrameIs(owner)) && (*i)->ShouldClose(reason)) {
      close_queue.push_back(std::move(*i));
      i = controllers_.erase(i);
    } else {
      ++i;
    }
  }
  manager_state_ = original_state;

  for (auto& controller : close_queue) {
    controller->DoClose(reason);

    for (auto& observer : observers_)
      observer.OnBubbleClosed(controller->AsWeakPtr(), reason);
  }

  return !close_queue.empty();
}
