// Copyright 2020 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/ambient/ui/media_string_view.h"

#include <memory>
#include <string>

#include "ash/ambient/ambient_constants.h"
#include "ash/ambient/ui/ambient_view_ids.h"
#include "ash/ambient/util/ambient_util.h"
#include "ash/public/cpp/ash_pref_names.h"
#include "ash/resources/vector_icons/vector_icons.h"
#include "ash/session/session_controller_impl.h"
#include "ash/shell.h"
#include "ash/shell_delegate.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "components/prefs/pref_service.h"
#include "services/media_session/public/cpp/media_session_service.h"
#include "services/media_session/public/mojom/media_session.mojom.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/paint_recorder.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/gfx/font.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/gfx/shadow_value.h"
#include "ui/gfx/skia_paint_util.h"
#include "ui/gfx/text_constants.h"
#include "ui/gfx/transform.h"
#include "ui/views/border.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/layout/flex_layout.h"
#include "ui/views/layout/flex_layout_types.h"
#include "ui/views/metadata/metadata_impl_macros.h"

namespace ash {

namespace {

// A layer delegate used for mask layer, with left and right gradient fading out
// zones.
class FadeoutLayerDelegate : public ui::LayerDelegate {
 public:
  FadeoutLayerDelegate() : layer_(ui::LAYER_TEXTURED) {
    layer_.set_delegate(this);
    layer_.SetFillsBoundsOpaquely(false);
  }

  ~FadeoutLayerDelegate() override { layer_.set_delegate(nullptr); }

  ui::Layer* layer() { return &layer_; }

 private:
  // ui::LayerDelegate:
  void OnPaintLayer(const ui::PaintContext& context) override {
    const gfx::Size& size = layer()->size();
    gfx::Rect left_rect(0, 0, kMediaStringGradientWidthDip, size.height());
    gfx::Rect right_rect(size.width() - kMediaStringGradientWidthDip, 0,
                         kMediaStringGradientWidthDip, size.height());

    views::PaintInfo paint_info =
        views::PaintInfo::CreateRootPaintInfo(context, size);
    const auto& prs = paint_info.paint_recording_size();

    // Pass the scale factor when constructing PaintRecorder so the MaskLayer
    // size is not incorrectly rounded (see https://crbug.com/921274).
    ui::PaintRecorder recorder(context, paint_info.paint_recording_size(),
                               static_cast<float>(prs.width()) / size.width(),
                               static_cast<float>(prs.height()) / size.height(),
                               nullptr);

    gfx::Canvas* canvas = recorder.canvas();
    // Clear the canvas.
    canvas->DrawColor(SK_ColorBLACK, SkBlendMode::kSrc);
    // Draw left gradient zone.
    cc::PaintFlags flags;
    flags.setBlendMode(SkBlendMode::kSrc);
    flags.setAntiAlias(false);
    flags.setShader(gfx::CreateGradientShader(
        gfx::Point(), gfx::Point(kMediaStringGradientWidthDip, 0),
        SK_ColorTRANSPARENT, SK_ColorBLACK));
    canvas->DrawRect(left_rect, flags);

    // Draw right gradient zone.
    flags.setShader(gfx::CreateGradientShader(
        gfx::Point(size.width() - kMediaStringGradientWidthDip, 0),
        gfx::Point(size.width(), 0), SK_ColorBLACK, SK_ColorTRANSPARENT));
    canvas->DrawRect(right_rect, flags);
  }

  void OnDeviceScaleFactorChanged(float old_device_scale_factor,
                                  float new_device_scale_factor) override {}

  ui::Layer layer_;
};

// Typography.
constexpr char kMiddleDotSeparator[] = " \u2022 ";

constexpr int kMusicNoteIconSizeDip = 20;

// Returns true if we should show media string for ambient mode on lock-screen
// based on user pref. We should keep the same user policy here as the
// lock-screen media controls to avoid exposing user data on lock-screen without
// consent.
bool ShouldShowOnLockScreen() {
  PrefService* pref =
      Shell::Get()->session_controller()->GetPrimaryUserPrefService();
  DCHECK(pref);

  return pref->GetBoolean(prefs::kLockScreenMediaControlsEnabled);
}

}  // namespace

MediaStringView::MediaStringView() {
  SetID(AmbientViewID::kAmbientMediaStringView);
  InitLayout();
}

MediaStringView::~MediaStringView() = default;

void MediaStringView::OnViewBoundsChanged(views::View* observed_view) {
  UpdateMaskLayer();
}

void MediaStringView::MediaSessionInfoChanged(
    media_session::mojom::MediaSessionInfoPtr session_info) {
  if (ambient::util::IsShowing(LockScreen::ScreenType::kLock) &&
      !ShouldShowOnLockScreen()) {
    return;
  }

  // Don't show the media string if session info is unavailable, or the active
  // session is marked as sensitive.
  if (!session_info || session_info->is_sensitive) {
    SetVisible(false);
    return;
  }

  bool is_paused = session_info->playback_state ==
                   media_session::mojom::MediaPlaybackState::kPaused;

  // Don't show the media string if paused.
  SetVisible(!is_paused);
}

void MediaStringView::MediaSessionMetadataChanged(
    const base::Optional<media_session::MediaMetadata>& metadata) {
  media_session::MediaMetadata session_metadata =
      metadata.value_or(media_session::MediaMetadata());

  std::u16string media_string;
  std::u16string middle_dot = base::UTF8ToUTF16(kMiddleDotSeparator);
  if (!session_metadata.title.empty() && !session_metadata.artist.empty()) {
    media_string =
        session_metadata.title + middle_dot + session_metadata.artist;
  } else if (!session_metadata.title.empty()) {
    media_string = session_metadata.title;
  } else {
    media_string = session_metadata.artist;
  }

  // Reset text and stop any ongoing animation.
  media_text_->SetText(std::u16string());
  media_text_->layer()->GetAnimator()->StopAnimating();

  media_text_->SetText(media_string);
  media_text_->layer()->SetTransform(gfx::Transform());
  const auto& text_size = media_text_->GetPreferredSize();
  const int text_width = text_size.width();
  media_text_container_->SetPreferredSize(gfx::Size(
      std::min(kMediaStringMaxWidthDip, text_width), text_size.height()));

  if (NeedToAnimate()) {
    media_text_->SetText(media_string + middle_dot + media_string + middle_dot);
    ScheduleScrolling(/*is_initial=*/true);
  }
}

void MediaStringView::OnImplicitAnimationsCompleted() {
  if (!NeedToAnimate())
    return;

  ScheduleScrolling(/*is_initial=*/false);
}

void MediaStringView::InitLayout() {
  // This view will be drawn on its own layer instead of the layer of
  // |PhotoView| which has a solid black background.
  SetPaintToLayer();
  layer()->SetFillsBoundsOpaquely(false);

  constexpr int kChildSpacingDip = 8;
  auto* layout = SetLayoutManager(std::make_unique<views::BoxLayout>(
      views::BoxLayout::Orientation::kHorizontal));
  layout->set_main_axis_alignment(views::BoxLayout::MainAxisAlignment::kStart);
  layout->set_cross_axis_alignment(
      views::BoxLayout::CrossAxisAlignment::kCenter);
  layout->set_between_child_spacing(kChildSpacingDip);

  icon_ = AddChildView(std::make_unique<views::ImageView>());
  icon_->SetPreferredSize(
      gfx::Size(kMusicNoteIconSizeDip, kMusicNoteIconSizeDip));
  icon_->SetImage(gfx::CreateVectorIcon(
      kMusicNoteIcon, kMusicNoteIconSizeDip,
      ambient::util::GetContentLayerColor(
          AshColorProvider::ContentLayerType::kIconColorPrimary)));

  media_text_container_ = AddChildView(std::make_unique<views::View>());
  media_text_container_->SetPaintToLayer();
  media_text_container_->layer()->SetFillsBoundsOpaquely(false);
  media_text_container_->layer()->SetMasksToBounds(true);
  auto* text_layout = media_text_container_->SetLayoutManager(
      std::make_unique<views::FlexLayout>());
  text_layout->SetOrientation(views::LayoutOrientation::kHorizontal);
  text_layout->SetMainAxisAlignment(views::LayoutAlignment::kStart);
  text_layout->SetCrossAxisAlignment(views::LayoutAlignment::kCenter);
  observed_view_.Observe(media_text_container_);

  media_text_ =
      media_text_container_->AddChildView(std::make_unique<views::Label>());
  media_text_->SetPaintToLayer();
  media_text_->layer()->SetFillsBoundsOpaquely(false);

  // Defines the appearance.
  constexpr int kDefaultFontSizeDip = 64;
  constexpr int kMediaStringFontSizeDip = 18;
  media_text_->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_TO_HEAD);
  media_text_->SetVerticalAlignment(gfx::VerticalAlignment::ALIGN_MIDDLE);
  media_text_->SetAutoColorReadabilityEnabled(false);
  media_text_->SetEnabledColor(ambient::util::GetContentLayerColor(
      AshColorProvider::ContentLayerType::kTextColorPrimary));
  media_text_->SetFontList(
      ambient::util::GetDefaultFontlist()
          .DeriveWithSizeDelta(kMediaStringFontSizeDip - kDefaultFontSizeDip)
          .DeriveWithWeight(gfx::Font::Weight::MEDIUM));
  media_text_->SetElideBehavior(gfx::ElideBehavior::NO_ELIDE);

  auto shadow_values = ambient::util::GetTextShadowValues();
  media_text_->SetShadows(shadow_values);
  gfx::Insets shadow_insets = gfx::ShadowValue::GetMargin(shadow_values);
  // Compensate the shadow insets to put the text middle align with the icon.
  media_text_->SetBorder(views::CreateEmptyBorder(
      /*top=*/-shadow_insets.bottom(),
      /*left=*/0,
      /*bottom=*/-shadow_insets.top(),
      /*right=*/0));

  BindMediaControllerObserver();
}

void MediaStringView::BindMediaControllerObserver() {
  media_session::MediaSessionService* service =
      Shell::Get()->shell_delegate()->GetMediaSessionService();
  // Service might be unavailable under some test environments.
  if (!service)
    return;

  // Binds to the MediaControllerManager and create a MediaController for the
  // current active media session so that we can observe it.
  mojo::Remote<media_session::mojom::MediaControllerManager>
      controller_manager_remote;
  service->BindMediaControllerManager(
      controller_manager_remote.BindNewPipeAndPassReceiver());
  controller_manager_remote->CreateActiveMediaController(
      media_controller_remote_.BindNewPipeAndPassReceiver());

  // Observe the active media controller for changes.
  media_controller_remote_->AddObserver(
      observer_receiver_.BindNewPipeAndPassRemote());
}

void MediaStringView::UpdateMaskLayer() {
  if (!NeedToAnimate()) {
    media_text_container_->layer()->SetMaskLayer(nullptr);
    return;
  }

  if (!fadeout_layer_delegate_) {
    fadeout_layer_delegate_ = std::make_unique<FadeoutLayerDelegate>();
    fadeout_layer_delegate_->layer()->SetBounds(
        media_text_container_->layer()->bounds());
  }
  media_text_container_->layer()->SetMaskLayer(
      fadeout_layer_delegate_->layer());
}

bool MediaStringView::NeedToAnimate() const {
  return media_text_->GetPreferredSize().width() >
         media_text_container_->GetPreferredSize().width();
}

gfx::Transform MediaStringView::GetMediaTextTransform(bool is_initial) {
  gfx::Transform transform;
  if (is_initial) {
    // Start animation half way of |media_text_container_|.
    transform.Translate(kMediaStringMaxWidthDip / 2, 0);
  }
  return transform;
}

void MediaStringView::ScheduleScrolling(bool is_initial) {
  if (!GetVisible())
    return;

  base::SequencedTaskRunnerHandle::Get()->PostTask(
      FROM_HERE, base::BindOnce(&MediaStringView::StartScrolling,
                                weak_factory_.GetWeakPtr(), is_initial));
}

void MediaStringView::StartScrolling(bool is_initial) {
  ui::Layer* text_layer = media_text_->layer();
  text_layer->SetTransform(GetMediaTextTransform(is_initial));
  {
    // Desired speed is 10 seconds for kMediaStringMaxWidthDip.
    const int text_width = media_text_->GetPreferredSize().width();
    const int shadow_width =
        gfx::ShadowValue::GetMargin(ambient::util::GetTextShadowValues())
            .width();
    const int start_x = text_layer->GetTargetTransform().To2dTranslation().x();
    const int end_x = -(text_width + shadow_width) / 2;
    const int transform_distance = start_x - end_x;
    const base::TimeDelta kScrollingDuration =
        base::TimeDelta::FromSeconds(10) * transform_distance /
        kMediaStringMaxWidthDip;

    ui::ScopedLayerAnimationSettings animation(text_layer->GetAnimator());
    animation.SetTransitionDuration(kScrollingDuration);
    animation.SetTweenType(gfx::Tween::LINEAR);
    animation.SetPreemptionStrategy(
        ui::LayerAnimator::IMMEDIATELY_SET_NEW_TARGET);
    animation.AddObserver(this);

    gfx::Transform transform;
    transform.Translate(end_x, 0);
    text_layer->SetTransform(transform);
  }
}

BEGIN_METADATA(MediaStringView, views::View)
END_METADATA

}  // namespace ash
