// 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/ui/panels/base_panel_browser_test.h"

#include "base/bind.h"
#include "base/command_line.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/strings/string_number_conversions.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/extension_prefs.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/panels/detached_panel_collection.h"
#include "chrome/browser/ui/panels/native_panel.h"
#include "chrome/browser/ui/panels/panel_collection.h"
#include "chrome/browser/ui/panels/panel_mouse_watcher.h"
#include "chrome/browser/ui/panels/stacked_panel_collection.h"
#include "chrome/browser/ui/panels/test_panel_active_state_observer.h"
#include "chrome/browser/ui/panels/test_panel_mouse_watcher.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/base/interactive_test_utils.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/notification_service.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/web_contents_tester.h"
#include "extensions/common/manifest_constants.h"
#include "sync/api/string_ordinal.h"

#if defined(OS_LINUX)
#include "chrome/browser/ui/browser_window.h"
#include "ui/base/x/x11_util.h"
#endif

#if defined(OS_LINUX) && !defined(USE_AURA)
#include "ui/base/x/active_window_watcher_x.h"
#endif

#if defined(OS_MACOSX)
#include "base/mac/scoped_nsautorelease_pool.h"
#include "chrome/browser/ui/cocoa/run_loop_testing.h"
#endif

using content::WebContentsTester;
using extensions::Extension;

namespace {

const gfx::Rect kTestingPrimaryDisplayArea = gfx::Rect(0, 0, 800, 600);
const gfx::Rect kTestingPrimaryWorkArea = gfx::Rect(0, 0, 800, 580);

struct MockDesktopBar {
  bool auto_hiding_enabled;
  DisplaySettingsProvider::DesktopBarVisibility visibility;
  int thickness;
};

class MockDisplaySettingsProviderImpl :
    public BasePanelBrowserTest::MockDisplaySettingsProvider {
 public:
  explicit MockDisplaySettingsProviderImpl();
  virtual ~MockDisplaySettingsProviderImpl() { }

  // Overridden from DisplaySettingsProvider:
  virtual gfx::Rect GetPrimaryDisplayArea() const OVERRIDE;
  virtual gfx::Rect GetPrimaryWorkArea() const OVERRIDE;
  virtual gfx::Rect GetDisplayAreaMatching(
      const gfx::Rect& bounds) const OVERRIDE;
  virtual gfx::Rect GetWorkAreaMatching(
      const gfx::Rect& bounds) const OVERRIDE;
  virtual bool IsAutoHidingDesktopBarEnabled(
      DesktopBarAlignment alignment) OVERRIDE;
  virtual int GetDesktopBarThickness(
      DesktopBarAlignment alignment) const OVERRIDE;
  virtual DesktopBarVisibility GetDesktopBarVisibility(
      DesktopBarAlignment alignment) const OVERRIDE;

  // Overridden from MockDisplaySettingsProvider:
  virtual void SetPrimaryDisplay(
      const gfx::Rect& display_area, const gfx::Rect& work_area) OVERRIDE;
  virtual void SetSecondaryDisplay(
      const gfx::Rect& display_area, const gfx::Rect& work_area) OVERRIDE;
  virtual void EnableAutoHidingDesktopBar(DesktopBarAlignment alignment,
                                          bool enabled,
                                          int thickness) OVERRIDE;
  virtual void SetDesktopBarVisibility(
      DesktopBarAlignment alignment, DesktopBarVisibility visibility) OVERRIDE;
  virtual void SetDesktopBarThickness(DesktopBarAlignment alignment,
                                      int thickness) OVERRIDE;

 private:
  gfx::Rect primary_display_area_;
  gfx::Rect primary_work_area_;
  gfx::Rect secondary_display_area_;
  gfx::Rect secondary_work_area_;
  MockDesktopBar mock_desktop_bars[3];

  DISALLOW_COPY_AND_ASSIGN(MockDisplaySettingsProviderImpl);
};


MockDisplaySettingsProviderImpl::MockDisplaySettingsProviderImpl() {
  memset(mock_desktop_bars, 0, sizeof(mock_desktop_bars));
}

gfx::Rect MockDisplaySettingsProviderImpl::GetPrimaryDisplayArea() const {
  return primary_display_area_;
}

gfx::Rect MockDisplaySettingsProviderImpl::GetPrimaryWorkArea() const {
  return primary_work_area_;
}

gfx::Rect MockDisplaySettingsProviderImpl::GetDisplayAreaMatching(
    const gfx::Rect& bounds) const {
  if (secondary_display_area_.IsEmpty())
    return primary_display_area_;

  gfx::Rect primary_intersection =
      gfx::IntersectRects(bounds, primary_display_area_);
  int primary_intersection_size =
      primary_intersection.width() * primary_intersection.height();

  gfx::Rect secondary_intersection =
      gfx::IntersectRects(bounds, secondary_display_area_);
  int secondary_intersection_size =
      secondary_intersection.width() * secondary_intersection.height();

  return primary_intersection_size >= secondary_intersection_size ?
      primary_display_area_ : secondary_display_area_;
}

gfx::Rect MockDisplaySettingsProviderImpl::GetWorkAreaMatching(
    const gfx::Rect& bounds) const {
  if (secondary_work_area_.IsEmpty())
    return primary_work_area_;

  gfx::Rect primary_intersection =
      gfx::IntersectRects(bounds, primary_work_area_);
  int primary_intersection_size =
      primary_intersection.width() * primary_intersection.height();

  gfx::Rect secondary_intersection =
      gfx::IntersectRects(bounds, secondary_work_area_);
  int secondary_intersection_size =
      secondary_intersection.width() * secondary_intersection.height();

  return primary_intersection_size >= secondary_intersection_size ?
      primary_work_area_ : secondary_work_area_;
}

bool MockDisplaySettingsProviderImpl::IsAutoHidingDesktopBarEnabled(
    DesktopBarAlignment alignment) {
  return mock_desktop_bars[static_cast<int>(alignment)].auto_hiding_enabled;
}

int MockDisplaySettingsProviderImpl::GetDesktopBarThickness(
    DesktopBarAlignment alignment) const {
  return mock_desktop_bars[static_cast<int>(alignment)].thickness;
}

DisplaySettingsProvider::DesktopBarVisibility
MockDisplaySettingsProviderImpl::GetDesktopBarVisibility(
    DesktopBarAlignment alignment) const {
  return mock_desktop_bars[static_cast<int>(alignment)].visibility;
}

void MockDisplaySettingsProviderImpl::EnableAutoHidingDesktopBar(
    DesktopBarAlignment alignment, bool enabled, int thickness) {
  MockDesktopBar* bar = &(mock_desktop_bars[static_cast<int>(alignment)]);
  bar->auto_hiding_enabled = enabled;
  bar->thickness = thickness;
}

void MockDisplaySettingsProviderImpl::SetPrimaryDisplay(
    const gfx::Rect& display_area, const gfx::Rect& work_area) {
  DCHECK(display_area.Contains(work_area));
  primary_display_area_ = display_area;
  primary_work_area_ = work_area;
  OnDisplaySettingsChanged();
}

void MockDisplaySettingsProviderImpl::SetSecondaryDisplay(
    const gfx::Rect& display_area, const gfx::Rect& work_area) {
  DCHECK(display_area.Contains(work_area));
  secondary_display_area_ = display_area;
  secondary_work_area_ = work_area;
  OnDisplaySettingsChanged();
}

void MockDisplaySettingsProviderImpl::SetDesktopBarVisibility(
    DesktopBarAlignment alignment, DesktopBarVisibility visibility) {
  MockDesktopBar* bar = &(mock_desktop_bars[static_cast<int>(alignment)]);
  if (!bar->auto_hiding_enabled)
    return;
  if (visibility == bar->visibility)
    return;
  bar->visibility = visibility;
  FOR_EACH_OBSERVER(
      DesktopBarObserver,
      desktop_bar_observers(),
      OnAutoHidingDesktopBarVisibilityChanged(alignment, visibility));
}

void MockDisplaySettingsProviderImpl::SetDesktopBarThickness(
    DesktopBarAlignment alignment, int thickness) {
  MockDesktopBar* bar = &(mock_desktop_bars[static_cast<int>(alignment)]);
  if (!bar->auto_hiding_enabled)
    return;
  if (thickness == bar->thickness)
    return;
  bar->thickness = thickness;
  FOR_EACH_OBSERVER(
      DesktopBarObserver,
      desktop_bar_observers(),
      OnAutoHidingDesktopBarThicknessChanged(alignment, thickness));
}

}  // namespace

const base::FilePath::CharType* BasePanelBrowserTest::kTestDir =
    FILE_PATH_LITERAL("panels");

BasePanelBrowserTest::BasePanelBrowserTest()
    : InProcessBrowserTest(),
      mock_display_settings_enabled_(true) {
}

BasePanelBrowserTest::~BasePanelBrowserTest() {
}

bool BasePanelBrowserTest::SkipTestIfIceWM() {
#if defined(OS_LINUX)
  return ui::GuessWindowManager() == ui::WM_ICE_WM;
#else
  return false;
#endif
}

bool BasePanelBrowserTest::SkipTestIfCompizWM() {
#if defined(OS_LINUX)
  return ui::GuessWindowManager() == ui::WM_COMPIZ;
#else
  return false;
#endif
}

void BasePanelBrowserTest::SetUpCommandLine(CommandLine* command_line) {
  command_line->AppendSwitch(switches::kEnablePanels);
}

void BasePanelBrowserTest::SetUpOnMainThread() {
  InProcessBrowserTest::SetUpOnMainThread();

  // Setup the work area and desktop bar so that we have consistent testing
  // environment for all panel related tests.
  if (mock_display_settings_enabled_) {
    mock_display_settings_provider_ = new MockDisplaySettingsProviderImpl();
    mock_display_settings_provider_->SetPrimaryDisplay(
        kTestingPrimaryDisplayArea, kTestingPrimaryWorkArea);
    PanelManager::SetDisplaySettingsProviderForTesting(
        mock_display_settings_provider_);
  }

  PanelManager* panel_manager = PanelManager::GetInstance();
  panel_manager->enable_auto_sizing(false);

  PanelManager::shorten_time_intervals_for_testing();

  // Simulate the mouse movement so that tests are not affected by actual mouse
  // events.
  PanelMouseWatcher* mouse_watcher = new TestPanelMouseWatcher();
  panel_manager->SetMouseWatcherForTesting(mouse_watcher);

  // This is needed so the subsequently created panels can be activated.
  // On a Mac, it transforms background-only test process into foreground one.
  ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
}

void BasePanelBrowserTest::WaitForPanelActiveState(
    Panel* panel, ActiveState expected_state) {
  DCHECK(expected_state == SHOW_AS_ACTIVE ||
         expected_state == SHOW_AS_INACTIVE);

#if defined(OS_MACOSX)
  scoped_ptr<NativePanelTesting> panel_testing(
      CreateNativePanelTesting(panel));
  ASSERT_TRUE(panel_testing->EnsureApplicationRunOnForeground()) <<
      "Failed to bring application to foreground. Bail out.";
#endif

  PanelActiveStateObserver signal(panel, expected_state == SHOW_AS_ACTIVE);
  signal.Wait();
}

void BasePanelBrowserTest::WaitForWindowSizeAvailable(Panel* panel) {
  scoped_ptr<NativePanelTesting> panel_testing(
      CreateNativePanelTesting(panel));
  content::WindowedNotificationObserver signal(
      chrome::NOTIFICATION_PANEL_WINDOW_SIZE_KNOWN,
      content::Source<Panel>(panel));
  if (panel_testing->IsWindowSizeKnown())
    return;
  signal.Wait();
  EXPECT_TRUE(panel_testing->IsWindowSizeKnown());
}

void BasePanelBrowserTest::WaitForBoundsAnimationFinished(Panel* panel) {
  scoped_ptr<NativePanelTesting> panel_testing(
      CreateNativePanelTesting(panel));
  // Sometimes there are several animations in sequence due to content
  // auto resizing. Wait for all animations to finish.
  while (panel_testing->IsAnimatingBounds()) {
    content::WindowedNotificationObserver signal(
        chrome::NOTIFICATION_PANEL_BOUNDS_ANIMATIONS_FINISHED,
        content::Source<Panel>(panel));
    if (!panel_testing->IsAnimatingBounds())
      return;
    signal.Wait();
  }
}

BasePanelBrowserTest::CreatePanelParams::CreatePanelParams(
    const std::string& name,
    const gfx::Rect& bounds,
    ActiveState show_flag)
    : name(name),
      bounds(bounds),
      show_flag(show_flag),
      wait_for_fully_created(true),
      expected_active_state(show_flag),
      create_mode(PanelManager::CREATE_AS_DOCKED),
      profile(NULL) {
}

Panel* BasePanelBrowserTest::CreatePanelWithParams(
    const CreatePanelParams& params) {
#if defined(OS_MACOSX)
  // Opening panels on a Mac causes NSWindowController of the Panel window
  // to be autoreleased. We need a pool drained after it's done so the test
  // can close correctly. The NSWindowController of the Panel window controls
  // lifetime of the Panel object so we want to release it as soon as
  // possible. In real Chrome, this is done by message pump.
  // On non-Mac platform, this is an empty class.
  base::mac::ScopedNSAutoreleasePool autorelease_pool;
#endif

  content::WindowedNotificationObserver observer(
      content::NOTIFICATION_LOAD_STOP,
      content::NotificationService::AllSources());

  PanelManager* manager = PanelManager::GetInstance();
  Panel* panel = manager->CreatePanel(
      params.name,
      params.profile ? params.profile : browser()->profile(),
      params.url,
      params.bounds,
      params.create_mode);

  if (!params.url.is_empty())
    observer.Wait();

  if (!manager->auto_sizing_enabled() ||
      params.bounds.width() || params.bounds.height()) {
    EXPECT_FALSE(panel->auto_resizable());
  } else {
    EXPECT_TRUE(panel->auto_resizable());
  }

  if (params.show_flag == SHOW_AS_ACTIVE) {
    panel->Show();
  } else {
    panel->ShowInactive();
  }

  if (params.wait_for_fully_created) {
    base::MessageLoopForUI::current()->RunUntilIdle();

#if defined(OS_LINUX)
    // On bots, we might have a simple window manager which always activates new
    // windows, and can't always deactivate them. Re-activate the main tabbed
    // browser to "deactivate" the newly created panel.
    if (params.expected_active_state == SHOW_AS_INACTIVE &&
        ui::GuessWindowManager() == ui::WM_ICE_WM) {
      // Wait for new panel to become active before deactivating to ensure
      // the activated notification is consumed before we wait for the panel
      // to become inactive.
      WaitForPanelActiveState(panel, SHOW_AS_ACTIVE);
      browser()->window()->Activate();
    }
#endif
    // More waiting, because gaining or losing focus may require inter-process
    // asynchronous communication, and it is not enough to just run the local
    // message loop to make sure this activity has completed.
    WaitForPanelActiveState(panel, params.expected_active_state);

    // On Linux, window size is not available right away and we should wait
    // before moving forward with the test.
    WaitForWindowSizeAvailable(panel);

    // Wait for the bounds animations on creation to finish.
    WaitForBoundsAnimationFinished(panel);
  }

  return panel;
}

Panel* BasePanelBrowserTest::CreatePanelWithBounds(
    const std::string& panel_name, const gfx::Rect& bounds) {
  CreatePanelParams params(panel_name, bounds, SHOW_AS_ACTIVE);
  return CreatePanelWithParams(params);
}

Panel* BasePanelBrowserTest::CreatePanel(const std::string& panel_name) {
  CreatePanelParams params(panel_name, gfx::Rect(), SHOW_AS_ACTIVE);
  return CreatePanelWithParams(params);
}

Panel* BasePanelBrowserTest::CreateDockedPanel(const std::string& name,
                                               const gfx::Rect& bounds) {
  Panel* panel = CreatePanelWithBounds(name, bounds);
  EXPECT_EQ(PanelCollection::DOCKED, panel->collection()->type());
  return panel;
}

Panel* BasePanelBrowserTest::CreateDetachedPanel(const std::string& name,
                                                 const gfx::Rect& bounds) {
  Panel* panel = CreatePanelWithBounds(name, bounds);
  PanelManager* panel_manager = panel->manager();
  panel_manager->MovePanelToCollection(panel,
                                       panel_manager->detached_collection(),
                                       PanelCollection::DEFAULT_POSITION);
  EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type());
  // The panel is first created as docked panel, which ignores the specified
  // origin in |bounds|. We need to reposition the panel after it becomes
  // detached.
  panel->SetPanelBounds(bounds);
  WaitForBoundsAnimationFinished(panel);
  return panel;
}

Panel* BasePanelBrowserTest::CreateStackedPanel(const std::string& name,
                                                const gfx::Rect& bounds,
                                                StackedPanelCollection* stack) {
  Panel* panel = CreateDetachedPanel(name, bounds);
  panel->manager()->MovePanelToCollection(
      panel,
      stack,
      static_cast<PanelCollection::PositioningMask>(
          PanelCollection::DEFAULT_POSITION |
          PanelCollection::COLLAPSE_TO_FIT));
  EXPECT_EQ(PanelCollection::STACKED, panel->collection()->type());
  WaitForBoundsAnimationFinished(panel);
  return panel;
}

Panel* BasePanelBrowserTest::CreateInactivePanel(const std::string& name) {
  // Create an active panel first, instead of inactive panel. This is because
  // certain window managers on Linux, like icewm, will always activate the
  // new window.
  Panel* panel = CreatePanel(name);

  DeactivatePanel(panel);
  WaitForPanelActiveState(panel, SHOW_AS_INACTIVE);

  return panel;
}

Panel* BasePanelBrowserTest::CreateInactiveDockedPanel(
    const std::string& name, const gfx::Rect& bounds) {
  // Create an active panel first, instead of inactive panel. This is because
  // certain window managers on Linux, like icewm, will always activate the
  // new window.
  Panel* panel = CreateDockedPanel(name, bounds);

  DeactivatePanel(panel);
  WaitForPanelActiveState(panel, SHOW_AS_INACTIVE);

  return panel;
}

Panel* BasePanelBrowserTest::CreateInactiveDetachedPanel(
    const std::string& name, const gfx::Rect& bounds) {
  // Create an active panel first, instead of inactive panel. This is because
  // certain window managers on Linux, like icewm, will always activate the
  // new window.
  Panel* panel = CreateDetachedPanel(name, bounds);

  DeactivatePanel(panel);
  WaitForPanelActiveState(panel, SHOW_AS_INACTIVE);

  return panel;
}

void BasePanelBrowserTest::ActivatePanel(Panel* panel) {
  // For certain window managers on Linux, the window activation/deactivation
  // signals might not be sent. To work around this, we explicitly deactivate
  // all other panels first.
#if defined(OS_LINUX)
  std::vector<Panel*> panels = PanelManager::GetInstance()->panels();
  for (std::vector<Panel*>::const_iterator iter = panels.begin();
       iter != panels.end(); ++iter) {
    Panel* current_panel = *iter;
    if (panel != current_panel)
      current_panel->Deactivate();
  }
#endif

  panel->Activate();
}

void BasePanelBrowserTest::DeactivatePanel(Panel* panel) {
#if defined(OS_LINUX)
  // For certain window managers on Linux, like icewm, panel activation and
  // deactivation notification might not get tiggered when non-panel window is
  // activated or deactivated. So we deactivate the panel directly.
  panel->Deactivate();
#else
  // Make the panel lose focus by activating the browser window. This is
  // because:
  // 1) On Windows, deactivating the panel window might cause the application
  //    to lose the foreground status. When this occurs, trying to activate
  //    the panel window again will not be allowed by the system.
  // 2) On MacOS, deactivating a window is not supported by Cocoa.
  browser()->window()->Activate();
#endif
}

// static
NativePanelTesting* BasePanelBrowserTest::CreateNativePanelTesting(
    Panel* panel) {
  return panel->native_panel()->CreateNativePanelTesting();
}

scoped_refptr<Extension> BasePanelBrowserTest::CreateExtension(
    const base::FilePath::StringType& path,
    extensions::Manifest::Location location,
    const DictionaryValue& extra_value) {
  extensions::ExtensionPrefs* extension_prefs =
      extensions::ExtensionPrefs::Get(browser()->profile());
  base::FilePath full_path = extension_prefs->install_directory().Append(path);

  scoped_ptr<DictionaryValue> input_value(extra_value.DeepCopy());
  input_value->SetString(extensions::manifest_keys::kVersion, "1.0.0.0");
  input_value->SetString(extensions::manifest_keys::kName, "Sample Extension");

  std::string error;
  scoped_refptr<Extension> extension = Extension::Create(
      full_path,  location, *input_value, Extension::NO_FLAGS, &error);
  EXPECT_TRUE(extension.get());
  EXPECT_STREQ("", error.c_str());
  browser()->profile()->GetExtensionService()->
      OnExtensionInstalled(extension.get(),
                           syncer::StringOrdinal(),
                           false /* no requirement errors */,
                           extensions::Blacklist::NOT_BLACKLISTED,
                           false /* don't wait for idle */);
  return extension;
}

void BasePanelBrowserTest::CloseWindowAndWait(Panel* panel) {
  // Closing a panel may involve several async tasks. Need to use
  // message pump and wait for the notification.
  PanelManager* manager = PanelManager::GetInstance();
  int panel_count = manager->num_panels();
  content::WindowedNotificationObserver signal(
      chrome::NOTIFICATION_PANEL_CLOSED,
      content::Source<Panel>(panel));
  panel->Close();
  signal.Wait();
  // Now we have one less panel.
  EXPECT_EQ(panel_count - 1, manager->num_panels());

#if defined(OS_MACOSX)
  // Mac window controllers may be autoreleased, and in the non-test
  // environment, may actually depend on the autorelease pool being recycled
  // with the run loop in order to perform important work. Replicate this in
  // the test environment.
  AutoreleasePool()->Recycle();

  // Make sure that everything has a chance to run.
  chrome::testing::NSRunLoopRunAllPending();
#endif  // OS_MACOSX
}

void BasePanelBrowserTest::MoveMouseAndWaitForExpansionStateChange(
    Panel* panel,
    const gfx::Point& position) {
  content::WindowedNotificationObserver signal(
      chrome::NOTIFICATION_PANEL_CHANGED_EXPANSION_STATE,
      content::Source<Panel>(panel));
  MoveMouse(position);
  signal.Wait();
}

void BasePanelBrowserTest::MoveMouse(const gfx::Point& position) {
  PanelManager::GetInstance()->mouse_watcher()->NotifyMouseMovement(position);
}

std::string BasePanelBrowserTest::MakePanelName(int index) {
  std::string panel_name("Panel");
  return panel_name + base::IntToString(index);
}

bool BasePanelBrowserTest::WmSupportWindowActivation() {
#if defined(OS_LINUX) && !defined(USE_AURA)
  return ui::ActiveWindowWatcherX::WMSupportsActivation();
#else
  return true;
#endif
}
