// 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 "ash/shelf/shelf_controller.h"

#include <algorithm>
#include <utility>

#include "ash/public/cpp/ash_pref_names.h"
#include "ash/public/cpp/remote_shelf_item_delegate.h"
#include "ash/public/cpp/shelf_item_delegate.h"
#include "ash/public/cpp/shelf_prefs.h"
#include "ash/root_window_controller.h"
#include "ash/session/session_controller.h"
#include "ash/shelf/home_button_delegate.h"
#include "ash/shelf/shelf.h"
#include "ash/shelf/shelf_constants.h"
#include "ash/shelf/shelf_widget.h"
#include "ash/shell.h"
#include "ash/strings/grit/ash_strings.h"
#include "ash/system/message_center/arc/arc_notification_constants.h"
#include "ash/wm/tablet_mode/tablet_mode_controller.h"
#include "base/auto_reset.h"
#include "base/bind.h"
#include "chromeos/strings/grit/chromeos_strings.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/prefs/pref_change_registrar.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/models/simple_menu_model.h"
#include "ui/base/ui_base_features.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/message_center/message_center.h"

namespace ash {

namespace {

// Returns the Shelf instance for the display with the given |display_id|.
Shelf* GetShelfForDisplay(int64_t display_id) {
  // The controller may be null for invalid ids or for displays being removed.
  RootWindowController* root_window_controller =
      Shell::GetRootWindowControllerWithDisplayId(display_id);
  return root_window_controller ? root_window_controller->shelf() : nullptr;
}

// Set each Shelf's auto-hide behavior from the per-display pref.
void SetShelfAutoHideFromPrefs() {
  // TODO(jamescook): The session state check should not be necessary, but
  // otherwise this wrongly tries to set the alignment on a secondary display
  // during login before the ShelfLockingManager is created.
  SessionController* session_controller = Shell::Get()->session_controller();
  PrefService* prefs = session_controller->GetLastActiveUserPrefService();
  if (!prefs || !session_controller->IsActiveUserSessionStarted())
    return;

  for (const auto& display : display::Screen::GetScreen()->GetAllDisplays()) {
    auto value = GetShelfAutoHideBehaviorPref(prefs, display.id());
    // Don't show the shelf in app mode.
    if (session_controller->IsRunningInAppMode())
      value = SHELF_AUTO_HIDE_ALWAYS_HIDDEN;
    Shelf* shelf = GetShelfForDisplay(display.id());
    if (shelf)
      shelf->SetAutoHideBehavior(value);
  }
}

// Set each Shelf's alignment from the per-display pref.
void SetShelfAlignmentFromPrefs() {
  // TODO(jamescook): The session state check should not be necessary, but
  // otherwise this wrongly tries to set the alignment on a secondary display
  // during login before the ShelfLockingManager is created.
  SessionController* session_controller = Shell::Get()->session_controller();
  PrefService* prefs = session_controller->GetLastActiveUserPrefService();
  if (!prefs || !session_controller->IsActiveUserSessionStarted())
    return;

  for (const auto& display : display::Screen::GetScreen()->GetAllDisplays()) {
    auto value = GetShelfAlignmentPref(prefs, display.id());
    Shelf* shelf = GetShelfForDisplay(display.id());
    if (shelf)
      shelf->SetAlignment(value);
  }
}

void UpdateShelfVisibility() {
  for (const auto& display : display::Screen::GetScreen()->GetAllDisplays()) {
    Shelf* shelf = GetShelfForDisplay(display.id());
    if (shelf)
      shelf->UpdateVisibilityState();
  }
}

// Set each Shelf's auto-hide behavior and alignment from the per-display prefs.
void SetShelfBehaviorsFromPrefs() {
  SetShelfAutoHideFromPrefs();

  // The shelf should always be bottom-aligned in tablet mode; alignment is
  // assigned from prefs when tablet mode is exited.
  if (Shell::Get()
          ->tablet_mode_controller()
          ->IsTabletModeWindowManagerEnabled()) {
    return;
  }

  SetShelfAlignmentFromPrefs();
}

}  // namespace

ShelfController::ShelfController()
    : is_notification_indicator_enabled_(
          features::IsNotificationIndicatorEnabled()),
      message_center_observer_(this) {
  // Set the delegate and title string for the back button.
  model_.SetShelfItemDelegate(ShelfID(kBackButtonId), nullptr);
  DCHECK_EQ(0, model_.ItemIndexByID(ShelfID(kBackButtonId)));
  ShelfItem back_item = model_.items()[0];
  back_item.title = l10n_util::GetStringUTF16(IDS_ASH_SHELF_BACK_BUTTON_TITLE);
  model_.Set(0, back_item);

  // Set the delegate and title string for the home button.
  model_.SetShelfItemDelegate(ShelfID(kAppListId),
                              std::make_unique<HomeButtonDelegate>());
  DCHECK_EQ(1, model_.ItemIndexByID(ShelfID(kAppListId)));
  ShelfItem launcher_item = model_.items()[1];
  launcher_item.title =
      l10n_util::GetStringUTF16(IDS_ASH_SHELF_APP_LIST_LAUNCHER_TITLE);
  model_.Set(1, launcher_item);

  model_.AddObserver(this);

  Shell::Get()->session_controller()->AddObserver(this);
  Shell::Get()->tablet_mode_controller()->AddObserver(this);
  Shell::Get()->window_tree_host_manager()->AddObserver(this);

  if (is_notification_indicator_enabled_)
    message_center_observer_.Add(message_center::MessageCenter::Get());
}

ShelfController::~ShelfController() {
  model_.RemoveObserver(this);
  model_.DestroyItemDelegates();
}

void ShelfController::Shutdown() {
  Shell::Get()->window_tree_host_manager()->RemoveObserver(this);
  Shell::Get()->tablet_mode_controller()->RemoveObserver(this);
  Shell::Get()->session_controller()->RemoveObserver(this);
}

// static
void ShelfController::RegisterProfilePrefs(PrefRegistrySimple* registry) {
  // These prefs are public for ChromeLauncherController's OnIsSyncingChanged.
  // See the pref names definitions for explanations of the synced, local, and
  // per-display behaviors.
  registry->RegisterStringPref(
      prefs::kShelfAutoHideBehavior, kShelfAutoHideBehaviorNever,
      user_prefs::PrefRegistrySyncable::SYNCABLE_PREF | PrefRegistry::PUBLIC);
  registry->RegisterStringPref(prefs::kShelfAutoHideBehaviorLocal,
                               std::string(), PrefRegistry::PUBLIC);
  registry->RegisterStringPref(
      prefs::kShelfAlignment, kShelfAlignmentBottom,
      user_prefs::PrefRegistrySyncable::SYNCABLE_PREF | PrefRegistry::PUBLIC);
  registry->RegisterStringPref(prefs::kShelfAlignmentLocal, std::string(),
                               PrefRegistry::PUBLIC);
  registry->RegisterDictionaryPref(prefs::kShelfPreferences,
                                   PrefRegistry::PUBLIC);
}

void ShelfController::BindRequest(mojom::ShelfControllerRequest request) {
  bindings_.AddBinding(this, std::move(request));
}

void ShelfController::AddObserver(
    mojom::ShelfObserverAssociatedPtrInfo observer) {
  mojom::ShelfObserverAssociatedPtr observer_ptr;
  observer_ptr.Bind(std::move(observer));

  // Synchronize two ShelfModel instances, one each owned by Ash and Chrome.
  // Notify Chrome of existing ShelfModel items and delegates created by Ash.
  for (int i = 0; i < model_.item_count(); ++i) {
    ShelfItem item = model_.items()[i];
    ShelfItemDelegate* delegate = model_.GetShelfItemDelegate(item.id);
    // Notify observers of the delegate before the items themselves; Chrome
    // creates default delegates if none exist, breaking ShelfWindowWatcher.
    if (delegate) {
      observer_ptr->OnShelfItemDelegateChanged(
          item.id, delegate->CreateInterfacePtrAndBind());
    }
    // Pass null images to avoid transport costs; clients don't use images.
    item.image = gfx::ImageSkia();
    observer_ptr->OnShelfItemAdded(i, item);
  }

  observers_.AddPtr(std::move(observer_ptr));
}

void ShelfController::AddShelfItem(int32_t index, const ShelfItem& item) {
  DCHECK(!applying_remote_shelf_model_changes_) << " Unexpected model change";
  index = index < 0 ? model_.item_count() : index;
  DCHECK_GT(index, 0) << " Items can not precede the AppList";
  DCHECK_LE(index, model_.item_count()) << " Index out of bounds";
  index = std::min(std::max(index, 1), model_.item_count());
  base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, true);
  model_.AddAt(index, item);
}

void ShelfController::RemoveShelfItem(const ShelfID& id) {
  DCHECK(!applying_remote_shelf_model_changes_) << " Unexpected model change";
  const int index = model_.ItemIndexByID(id);
  DCHECK_GE(index, 0) << " No item found with the id: " << id;
  DCHECK_NE(index, 0) << " The AppList shelf item cannot be removed";
  if (index <= 0)
    return;
  base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, true);
  model_.RemoveItemAt(index);
}

void ShelfController::MoveShelfItem(const ShelfID& id, int32_t index) {
  DCHECK(!applying_remote_shelf_model_changes_) << " Unexpected model change";
  const int current_index = model_.ItemIndexByID(id);
  DCHECK_GE(current_index, 0) << " No item found with the id: " << id;
  DCHECK_NE(current_index, 0) << " The AppList shelf item cannot be moved";
  if (current_index <= 0)
    return;
  DCHECK_GT(index, 0) << " Items can not precede the AppList";
  DCHECK_LT(index, model_.item_count()) << " Index out of bounds";
  index = std::min(std::max(index, 1), model_.item_count() - 1);
  if (current_index == index) {
    DVLOG(1) << "The item is already at the given index (" << index << "). "
             << "This happens when syncing a ShelfModel weight reordering.";
    return;
  }
  base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, true);
  model_.Move(current_index, index);
}

void ShelfController::UpdateShelfItem(const ShelfItem& item) {
  DCHECK(!applying_remote_shelf_model_changes_) << " Unexpected model change";
  const int index = model_.ItemIndexByID(item.id);
  DCHECK_GE(index, 0) << " No item found with the id: " << item.id;
  if (index < 0)
    return;
  base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, true);

  // Keep any existing image if the item was sent without one for efficiency.
  ShelfItem new_item = item;
  if (item.image.isNull())
    new_item.image = model_.items()[index].image;
  model_.Set(index, new_item);
}

void ShelfController::SetShelfItemDelegate(
    const ShelfID& id,
    mojom::ShelfItemDelegatePtr delegate) {
  DCHECK(!applying_remote_shelf_model_changes_) << " Unexpected model change";
  base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, true);
  if (delegate.is_bound())
    model_.SetShelfItemDelegate(
        id, std::make_unique<RemoteShelfItemDelegate>(id, std::move(delegate)));
  else
    model_.SetShelfItemDelegate(id, nullptr);
}

void ShelfController::GetAutoHideBehaviorForTesting(
    int64_t display_id,
    GetAutoHideBehaviorForTestingCallback callback) {
  Shelf* shelf = GetShelfForDisplay(display_id);
  DCHECK(shelf);
  std::move(callback).Run(shelf->auto_hide_behavior());
}

void ShelfController::SetAutoHideBehaviorForTesting(
    int64_t display_id,
    ShelfAutoHideBehavior behavior,
    SetAutoHideBehaviorForTestingCallback callback) {
  Shelf* shelf = GetShelfForDisplay(display_id);
  DCHECK(shelf);
  shelf->SetAutoHideBehavior(behavior);
  std::move(callback).Run();
}

void ShelfController::ShelfItemAdded(int index) {
  if (applying_remote_shelf_model_changes_)
    return;

  // Pass null images to avoid transport costs; clients don't use images.
  ShelfItem item = model_.items()[index];
  item.image = gfx::ImageSkia();
  observers_.ForAllPtrs([index, item](mojom::ShelfObserver* observer) {
    observer->OnShelfItemAdded(index, item);
  });
}

void ShelfController::ShelfItemRemoved(int index, const ShelfItem& old_item) {
  if (applying_remote_shelf_model_changes_)
    return;

  observers_.ForAllPtrs([old_item](mojom::ShelfObserver* observer) {
    observer->OnShelfItemRemoved(old_item.id);
  });
}

void ShelfController::ShelfItemMoved(int start_index, int target_index) {
  if (applying_remote_shelf_model_changes_)
    return;

  const ShelfItem& item = model_.items()[target_index];
  observers_.ForAllPtrs([item, target_index](mojom::ShelfObserver* observer) {
    observer->OnShelfItemMoved(item.id, target_index);
  });
}

void ShelfController::ShelfItemChanged(int index, const ShelfItem& old_item) {
  if (applying_remote_shelf_model_changes_)
    return;

  // Pass null images to avoid transport costs; clients don't use images.
  ShelfItem item = model_.items()[index];
  item.image = gfx::ImageSkia();
  observers_.ForAllPtrs([item](mojom::ShelfObserver* observer) {
    observer->OnShelfItemUpdated(item);
  });
}

void ShelfController::ShelfItemDelegateChanged(const ShelfID& id,
                                               ShelfItemDelegate* old_delegate,
                                               ShelfItemDelegate* delegate) {
  if (applying_remote_shelf_model_changes_)
    return;

  observers_.ForAllPtrs([id, delegate](mojom::ShelfObserver* observer) {
    observer->OnShelfItemDelegateChanged(
        id, delegate ? delegate->CreateInterfacePtrAndBind()
                     : mojom::ShelfItemDelegatePtr());
  });
}

void ShelfController::FlushForTesting() {
  bindings_.FlushForTesting();
}

void ShelfController::OnActiveUserPrefServiceChanged(
    PrefService* pref_service) {
  SetShelfBehaviorsFromPrefs();
  pref_change_registrar_ = std::make_unique<PrefChangeRegistrar>();
  pref_change_registrar_->Init(pref_service);
  pref_change_registrar_->Add(prefs::kShelfAlignmentLocal,
                              base::BindRepeating(&SetShelfAlignmentFromPrefs));
  pref_change_registrar_->Add(prefs::kShelfAutoHideBehaviorLocal,
                              base::BindRepeating(&SetShelfAutoHideFromPrefs));
  pref_change_registrar_->Add(prefs::kShelfPreferences,
                              base::BindRepeating(&SetShelfBehaviorsFromPrefs));
}

void ShelfController::OnTabletModeStarted() {
  // Do nothing when running in app mode.
  if (Shell::Get()->session_controller()->IsRunningInAppMode())
    return;

  // Force the shelf to be visible and to be bottom aligned in tablet mode; the
  // prefs are restored on exit.
  for (const auto& display : display::Screen::GetScreen()->GetAllDisplays()) {
    Shelf* shelf = GetShelfForDisplay(display.id());
    if (shelf) {
      // Only animate into tablet mode if the shelf alignment will not change.
      if (shelf->IsHorizontalAlignment())
        shelf->set_is_tablet_mode_animation_running(true);
      shelf->SetAlignment(SHELF_ALIGNMENT_BOTTOM);
      shelf->shelf_widget()->OnTabletModeChanged();
    }
  }
}

void ShelfController::OnTabletModeEnded() {
  // Do nothing when running in app mode.
  if (Shell::Get()->session_controller()->IsRunningInAppMode())
    return;

  SetShelfBehaviorsFromPrefs();
  // Only animate out of tablet mode if the shelf alignment will not change.
  for (const auto& display : display::Screen::GetScreen()->GetAllDisplays()) {
    Shelf* shelf = GetShelfForDisplay(display.id());
    if (shelf) {
      if (shelf->IsHorizontalAlignment())
        shelf->set_is_tablet_mode_animation_running(true);
      shelf->shelf_widget()->OnTabletModeChanged();
    }
  }
}

void ShelfController::OnDisplayConfigurationChanged() {
  // Set/init the shelf behaviors from preferences, in case a display was added.
  SetShelfBehaviorsFromPrefs();

  // Update shelf visibility to adapt to display changes. For instance shelf
  // should be hidden on secondary display during inactive session states.
  UpdateShelfVisibility();
}

void ShelfController::OnWindowTreeHostReusedForDisplay(
    AshWindowTreeHost* window_tree_host,
    const display::Display& display) {
  // See comment in OnWindowTreeHostsSwappedDisplays().
  SetShelfBehaviorsFromPrefs();

  // Update shelf visibility to adapt to display changes. For instance shelf
  // should be hidden on secondary display during inactive session states.
  UpdateShelfVisibility();
}

void ShelfController::OnWindowTreeHostsSwappedDisplays(
    AshWindowTreeHost* host1,
    AshWindowTreeHost* host2) {
  // The display ids for existing shelf instances may have changed, so update
  // the alignment and auto-hide state from prefs. See http://crbug.com/748291
  SetShelfBehaviorsFromPrefs();

  // Update shelf visibility to adapt to display changes. For instance shelf
  // should be hidden on secondary display during inactive session states.
  UpdateShelfVisibility();
}

void ShelfController::OnNotificationAdded(const std::string& notification_id) {
  if (!is_notification_indicator_enabled_)
    return;

  message_center::Notification* notification =
      message_center::MessageCenter::Get()->FindVisibleNotificationById(
          notification_id);

  if (!notification)
    return;

  // Skip this if the notification shouldn't badge an app.
  if (notification->notifier_id().type !=
          message_center::NotifierType::APPLICATION &&
      notification->notifier_id().type !=
          message_center::NotifierType::ARC_APPLICATION) {
    return;
  }

  // Skip this if the notification doesn't have a valid app id.
  if (notification->notifier_id().id == kDefaultArcNotifierId)
    return;

  model_.AddNotificationRecord(notification->notifier_id().id, notification_id);
}

void ShelfController::OnNotificationRemoved(const std::string& notification_id,
                                            bool by_user) {
  if (!is_notification_indicator_enabled_)
    return;

  model_.RemoveNotificationRecord(notification_id);
}

}  // namespace ash
