// Copyright (c) 2012 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 "chrome/browser/extensions/extension_infobar_delegate.h"

#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extension_process_manager.h"
#include "chrome/browser/extensions/extension_system.h"
#include "chrome/browser/infobars/infobar.h"
#include "chrome/browser/infobars/infobar_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/extensions/extension.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_source.h"


ExtensionInfoBarDelegate::~ExtensionInfoBarDelegate() {
  if (observer_)
    observer_->OnDelegateDeleted();
}

// static
void ExtensionInfoBarDelegate::Create(InfoBarService* infobar_service,
                                      Browser* browser,
                                      const extensions::Extension* extension,
                                      const GURL& url,
                                      int height) {
  infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>(
      new ExtensionInfoBarDelegate(browser, infobar_service, extension, url,
                                   infobar_service->web_contents(), height)));
}

ExtensionInfoBarDelegate::ExtensionInfoBarDelegate(
    Browser* browser,
    InfoBarService* infobar_service,
    const extensions::Extension* extension,
    const GURL& url,
    content::WebContents* web_contents,
    int height)
    : InfoBarDelegate(infobar_service),
#if defined(TOOLKIT_VIEWS)
      browser_(browser),
#endif
      observer_(NULL),
      extension_(extension),
      closing_(false) {
  ExtensionProcessManager* manager =
      extensions::ExtensionSystem::Get(browser->profile())->process_manager();
  extension_host_.reset(manager->CreateInfobarHost(url, browser));
  extension_host_->SetAssociatedWebContents(web_contents);

  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE,
                 content::Source<Profile>(browser->profile()));
  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
                 content::Source<Profile>(browser->profile()));

#if defined(TOOLKIT_VIEWS) || defined(TOOLKIT_GTK) || defined(OS_ANDROID)
  // TODO(dtrainor): On Android, this is not used.  Might need to pull this from
  // Android UI level in the future.  Tracked via issue 115303.
  int default_height = InfoBar::kDefaultBarTargetHeight;
#elif defined(OS_MACOSX)
  // TODO(pkasting): Once Infobars have been ported to Mac, we can remove the
  // ifdefs and just use the Infobar constant below.
  int default_height = 36;
#endif
  height_ = std::max(0, height);
  height_ = std::min(2 * default_height, height_);
  if (height_ == 0)
    height_ = default_height;
}

bool ExtensionInfoBarDelegate::EqualsDelegate(InfoBarDelegate* delegate) const {
  ExtensionInfoBarDelegate* extension_delegate =
      delegate->AsExtensionInfoBarDelegate();
  // When an extension crashes, an InfoBar is shown (for the crashed extension).
  // That will result in a call to this function (to see if this InfoBarDelegate
  // is already showing the 'extension crashed InfoBar', which it never is), but
  // if it is our extension that crashes, the extension delegate is NULL so
  // we cannot check.
  if (!extension_delegate)
    return false;

  // Only allow one InfoBar at a time per extension.
  return extension_delegate->extension_host()->extension() ==
         extension_host_->extension();
}

void ExtensionInfoBarDelegate::InfoBarDismissed() {
  closing_ = true;
}

InfoBarDelegate::Type ExtensionInfoBarDelegate::GetInfoBarType() const {
  return PAGE_ACTION_TYPE;
}

ExtensionInfoBarDelegate*
    ExtensionInfoBarDelegate::AsExtensionInfoBarDelegate() {
  return this;
}

void ExtensionInfoBarDelegate::Observe(
    int type,
    const content::NotificationSource& source,
    const content::NotificationDetails& details) {
  if (type == chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE) {
    if (extension_host_.get() ==
        content::Details<extensions::ExtensionHost>(details).ptr())
      RemoveSelf();
  } else {
    DCHECK(type == chrome::NOTIFICATION_EXTENSION_UNLOADED);
    if (extension_ == content::Details<extensions::UnloadedExtensionInfo>(
        details)->extension)
      RemoveSelf();
  }
}
