// Copyright 2020 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/dom/lottie_player.h"

#include <memory>
#include <string>
#include <utility>

#include "base/strings/string_number_conversions.h"
#include "base/trace_event/trace_event.h"
#include "cobalt/base/polymorphic_downcast.h"
#include "cobalt/dom/document.h"
#include "cobalt/dom/dom_settings.h"
#include "cobalt/dom/html_element_context.h"
#include "cobalt/dom/lottie_frame_custom_event.h"
#include "cobalt/dom/window.h"
#include "cobalt/script/global_environment.h"
#include "cobalt/web/csp_delegate.h"
#include "url/gurl.h"

namespace cobalt {
namespace dom {

using render_tree::LottieAnimation;

const char LottiePlayer::kTagName[] = "lottie-player";

LottiePlayer::LottiePlayer(Document* document)
    : HTMLElement(document, base::Token(kTagName)),
      autoplaying_(true),
      ALLOW_THIS_IN_INITIALIZER_LIST(event_queue_(this)),
      callback_task_runner_(base::MessageLoop::current()->task_runner()) {
  SetAnimationEventCallbacks();
}

std::string LottiePlayer::src() const {
  return GetAttribute("src").value_or("");
}

void LottiePlayer::set_src(const std::string& src) { SetAttribute("src", src); }

bool LottiePlayer::autoplay() const { return GetBooleanAttribute("autoplay"); }

void LottiePlayer::set_autoplay(bool autoplay) {
  // The value of 'autoplay' is true when the 'autoplay' attribute is present.
  // The value of the attribute is irrelevant.
  if (autoplay) {
    SetBooleanAttribute("autoplay", true);
  } else {
    SetBooleanAttribute("autoplay", false);
  }
}

std::string LottiePlayer::background() const {
  return GetAttribute("background").value_or("");
}

void LottiePlayer::set_background(std::string background) {
  SetAttribute("background", background);
}

int LottiePlayer::count() const { return properties_.count; }

void LottiePlayer::set_count(int count) {
  SetAttribute("count", base::Int32ToString(count));
}

int LottiePlayer::direction() const { return properties_.direction; }

void LottiePlayer::set_direction(int direction) {
  SetAttribute("direction", base::Int32ToString(direction));
}

bool LottiePlayer::hover() const { return GetBooleanAttribute("hover"); }

void LottiePlayer::set_hover(bool hover) {
  // The value of 'hover' is true when the 'hover' attribute is present.
  // The value of the attribute is irrelevant.
  if (hover) {
    SetBooleanAttribute("hover", true);
  } else {
    SetBooleanAttribute("hover", false);
  }
}

bool LottiePlayer::loop() const { return properties_.loop; }

void LottiePlayer::set_loop(bool loop) {
  // The value of 'loop' is true when the 'loop' attribute is present.
  // The value of the attribute is irrelevant.
  if (loop) {
    SetBooleanAttribute("loop", true);
  } else {
    SetBooleanAttribute("loop", false);
  }
}

std::string LottiePlayer::mode() const { return properties_.GetModeAsString(); }

void LottiePlayer::set_mode(std::string mode) { SetAttribute("mode", mode); }

double LottiePlayer::speed() const { return properties_.speed; }

void LottiePlayer::set_speed(double speed) {
  SetAttribute("speed", base::NumberToString(speed));
}

std::string LottiePlayer::preserve_aspect_ratio() const {
  // Skottie animations default to "xMidYMid meet", meaning that the animation
  // will be uniformly scaled and centered relative to the element's width and
  // height.
  return "xMidYMid meet";
}

std::string LottiePlayer::renderer() const {
// Cobalt uses a custom compiled-in renderer.
#if defined(USE_SKIA_NEXT)
  return "skottie-m97";
#else
  return "skottie-m79";
#endif
}

void LottiePlayer::Load(std::string src) {
  // https://github.com/LottieFiles/lottie-player#loadsrc-string--object--void
  set_src(src);
}

void LottiePlayer::Play() {
  // https://lottiefiles.github.io/lottie-player/methods.html#play--void
  UpdateState(LottieAnimation::LottieState::kPlaying);
}

void LottiePlayer::Pause() {
  // https://lottiefiles.github.io/lottie-player/methods.html#pause--void
  UpdateState(LottieAnimation::LottieState::kPaused);
}

void LottiePlayer::Stop() {
  // https://lottiefiles.github.io/lottie-player/methods.html#stop--void
  UpdateState(LottieAnimation::LottieState::kStopped);
}

void LottiePlayer::Seek(FrameType frame) {
  // https://lottiefiles.github.io/lottie-player/methods.html#seekvalue-number--string--void
  if (frame.IsType<double>()) {
    properties_.SeekFrame(frame.AsType<double>());
  } else if (frame.IsType<std::string>()) {
    // Check whether a valid percent string.
    std::string frame_string = frame.AsType<std::string>();
    if (frame_string.empty()) {
      DLOG(WARNING) << "Percent string cannot be empty.";
      return;
    }
    double frame_percent;
    bool prefix_is_num = base::StringToDouble(
        frame_string.substr(0, frame_string.length() - 1), &frame_percent);
    if (frame_string.back() != '%' || !prefix_is_num) {
      DLOG(WARNING) << "Not a valid percent string: "
                    << frame.AsType<std::string>();
      return;
    }
    properties_.SeekPercent(frame_percent);
  }

  UpdateLottieObjects();
}

void LottiePlayer::SetDirection(int direction) {
  // https://lottiefiles.github.io/lottie-player/methods.html#setdirectionvalue-number--void
  if (properties_.UpdateDirection(direction)) {
    UpdateLottieObjects();
  }
}

void LottiePlayer::SetLooping(bool loop) {
  // https://lottiefiles.github.io/lottie-player/methods.html#setloopingvalue-boolean--void
  if (properties_.UpdateLoop(loop)) {
    UpdateLottieObjects();
  }
}

void LottiePlayer::SetSpeed(double speed) {
  // https://lottiefiles.github.io/lottie-player/methods.html#setspeedvalue-number--void
  if (properties_.UpdateSpeed(speed)) {
    UpdateLottieObjects();
  }
}

void LottiePlayer::ToggleLooping() {
  // https://github.com/LottieFiles/lottie-player#togglelooping--void
  properties_.ToggleLooping();
  UpdateLottieObjects();
}

void LottiePlayer::TogglePlay() {
  // https://github.com/LottieFiles/lottie-player#toggleplay--void
  properties_.TogglePlay();

  UpdateLottieObjects();
}

LottieAnimation::LottieProperties LottiePlayer::GetProperties() const {
  return properties_;
}

void LottiePlayer::OnHover() {
  if (hover()) {
    UpdateState(LottieAnimation::LottieState::kPlaying);
  }
}

void LottiePlayer::OnUnHover() {
  if (hover()) {
    UpdateState(LottieAnimation::LottieState::kStopped);
  }
}

void LottiePlayer::PurgeCachedBackgroundImagesOfNodeAndDescendants() {
  if (!cached_image_loaded_callback_handler_) {
    return;
  }

  // While we are still loading, treat this as an error.
  OnLoadingError();
}

void LottiePlayer::OnSetAttribute(const std::string& name,
                                  const std::string& value) {
  if (name == "src") {
    UpdateAnimationData();
  } else if (name == "background") {
    SetStyleAttribute("background:" + value);
  } else if (name == "count") {
    int count;
    base::StringToInt32(value, &count);
    SetCount(count);
  } else if (name == "direction") {
    int direction;
    base::StringToInt32(value, &direction);
    SetDirection(direction);
  } else if (name == "loop") {
    SetLooping(true);
  } else if (name == "mode") {
    SetMode(value);
  } else if (name == "speed") {
    double speed;
    base::StringToDouble(value, &speed);
    SetSpeed(speed);
  } else {
    HTMLElement::OnSetAttribute(name, value);
  }
}

void LottiePlayer::OnRemoveAttribute(const std::string& name) {
  if (name == "src") {
    UpdateAnimationData();
  } else if (name == "background") {
    SetStyleAttribute("background:transparent");
  } else if (name == "count") {
    SetCount(LottieAnimation::LottieProperties::kDefaultCount);
  } else if (name == "direction") {
    SetDirection(LottieAnimation::LottieProperties::kDefaultDirection);
  } else if (name == "loop") {
    SetLooping(LottieAnimation::LottieProperties::kDefaultLoop);
  } else if (name == "mode") {
    SetMode(LottieAnimation::LottieProperties::kDefaultMode);
  } else if (name == "speed") {
    SetSpeed(LottieAnimation::LottieProperties::kDefaultSpeed);
  } else {
    HTMLElement::OnRemoveAttribute(name);
  }
}

void LottiePlayer::UpdateAnimationData() {
  DCHECK(base::MessageLoop::current());
  DCHECK(node_document());
  TRACE_EVENT0("cobalt::dom", "LottiePlayer::UpdateAnimationData()");

  if (cached_image_loaded_callback_handler_) {
    cached_image_loaded_callback_handler_.reset();
    prevent_gc_until_load_complete_.reset();
    node_document()->DecreaseLoadingCounter();
  }

  const std::string src = GetAttribute("src").value_or("");

  if (!src.empty()) {
    const GURL& base_url = node_document()->location()->url();
    const GURL selected_source = base_url.Resolve(src);
    if (!selected_source.is_valid()) {
      LOG(WARNING) << src << " cannot be resolved based on " << base_url << ".";
      return;
    }

    auto image_cache = node_document()->html_element_context()->image_cache();
    cached_image_ = image_cache->GetOrCreateCachedResource(selected_source,
                                                           loader::Origin());

    if (cached_image_->TryGetResource()) {
      PreventGarbageCollectionUntilEventIsDispatched(base::Tokens::load());
      // The requested resource has already been loaded. Trigger the "load" and
      // "ready" events to indicate that the animation data is already loaded
      // and the DOM element is already ready.
      ScheduleEvent(base::Tokens::load());
      ScheduleEvent(base::Tokens::ready());
      return;
    }
  } else {
    PreventGarbageCollectionUntilEventIsDispatched(base::Tokens::error());
    return;
  }

  DCHECK(!prevent_gc_until_load_complete_);
  prevent_gc_until_load_complete_.reset(
      new script::GlobalEnvironment::ScopedPreventGarbageCollection(
          html_element_context()->script_runner()->GetGlobalEnvironment(),
          this));
  node_document()->IncreaseLoadingCounter();
  cached_image_loaded_callback_handler_.reset(
      new loader::image::CachedImage::OnLoadedCallbackHandler(
          cached_image_,
          base::Bind(&LottiePlayer::OnLoadingSuccess, base::Unretained(this)),
          base::Bind(&LottiePlayer::OnLoadingError, base::Unretained(this))));
}

void LottiePlayer::OnLoadingSuccess() {
  TRACE_EVENT0("cobalt::dom", "LottiePlayer::OnLoadingSuccess()");
  AllowGarbageCollectionAfterEventIsDispatched(
      base::Tokens::load(), std::move(prevent_gc_until_load_complete_));
  if (node_document()) {
    node_document()->DecreaseLoadingCounterAndMaybeDispatchLoadEvent();
  }
  cached_image_loaded_callback_handler_.reset();

  // Set up the Lottie objects in the box and render trees once the file has
  // successfully loaded.
  UpdateLottieObjects();
  // Trigger a load event to indicate that the animation data has loaded, and
  // then a "ready" event to indicate the DOM element is ready.
  ScheduleEvent(base::Tokens::load());
  ScheduleEvent(base::Tokens::ready());
  // If the animation is autoplaying and autoplay is true, then the animation
  // playback state needs to be set to LottieAnimation::LottieState::kPlaying.
  UpdatePlaybackStateIfAutoplaying();
}

void LottiePlayer::OnLoadingError() {
  TRACE_EVENT0("cobalt::dom", "LottiePlayer::OnLoadingError()");
  AllowGarbageCollectionAfterEventIsDispatched(
      base::Tokens::error(), std::move(prevent_gc_until_load_complete_));
  if (node_document()) {
    node_document()->DecreaseLoadingCounterAndMaybeDispatchLoadEvent();
  }
  cached_image_loaded_callback_handler_.reset();
  ScheduleEvent(base::Tokens::error());
}

void LottiePlayer::PreventGarbageCollectionUntilEventIsDispatched(
    base::Token event_name) {
  std::unique_ptr<script::GlobalEnvironment::ScopedPreventGarbageCollection>
      prevent_gc_until_event_dispatch(
          new script::GlobalEnvironment::ScopedPreventGarbageCollection(
              html_element_context()->script_runner()->GetGlobalEnvironment(),
              this));
  AllowGarbageCollectionAfterEventIsDispatched(
      event_name, std::move(prevent_gc_until_event_dispatch));
}

void LottiePlayer::AllowGarbageCollectionAfterEventIsDispatched(
    base::Token event_name,
    std::unique_ptr<script::GlobalEnvironment::ScopedPreventGarbageCollection>
        scoped_prevent_gc) {
  PostToDispatchEventNameAndRunCallback(
      FROM_HERE, event_name,
      base::Bind(&LottiePlayer::DestroyScopedPreventGC,
                 base::AsWeakPtr<LottiePlayer>(this),
                 base::Passed(&scoped_prevent_gc)));
}

void LottiePlayer::DestroyScopedPreventGC(
    std::unique_ptr<script::GlobalEnvironment::ScopedPreventGarbageCollection>
        scoped_prevent_gc) {
  scoped_prevent_gc.reset();
}

void LottiePlayer::UpdateState(LottieAnimation::LottieState state) {
  if (properties_.UpdateState(state)) {
    UpdateLottieObjects();
  }
}

void LottiePlayer::UpdatePlaybackStateIfAutoplaying() {
  if (autoplaying_ && autoplay()) {
    properties_.UpdateState(LottieAnimation::LottieState::kPlaying);
  }
  autoplaying_ = false;
}

void LottiePlayer::SetCount(int count) {
  if (properties_.UpdateCount(count)) {
    UpdateLottieObjects();
  }
}

void LottiePlayer::SetMode(std::string mode) {
  if (properties_.UpdateMode(mode)) {
    UpdateLottieObjects();
  }
}

void LottiePlayer::SetMode(LottieAnimation::LottieMode mode) {
  if (properties_.UpdateMode(mode)) {
    UpdateLottieObjects();
  }
}

void LottiePlayer::UpdateLottieObjects() {
  node_document()->RecordMutation();
  InvalidateLayoutBoxesOfNodeAndAncestors();
}

void LottiePlayer::ScheduleEvent(base::Token event_name) {
  // https://github.com/LottieFiles/lottie-player#events
  scoped_refptr<web::Event> event = new web::Event(event_name);
  event->set_target(this);
  event_queue_.Enqueue(event);
}

void LottiePlayer::SetAnimationEventCallbacks() {
  DCHECK(callback_task_runner_);
  properties_.onplay_callback =
      base::Bind(base::IgnoreResult(&base::SingleThreadTaskRunner::PostTask),
                 callback_task_runner_, FROM_HERE,
                 base::Bind(&LottiePlayer::OnPlay, base::AsWeakPtr(this)));
  properties_.onpause_callback =
      base::Bind(base::IgnoreResult(&base::SingleThreadTaskRunner::PostTask),
                 callback_task_runner_, FROM_HERE,
                 base::Bind(&LottiePlayer::OnPause, base::AsWeakPtr(this)));
  properties_.onstop_callback =
      base::Bind(base::IgnoreResult(&base::SingleThreadTaskRunner::PostTask),
                 callback_task_runner_, FROM_HERE,
                 base::Bind(&LottiePlayer::OnStop, base::AsWeakPtr(this)));
  properties_.oncomplete_callback =
      base::Bind(base::IgnoreResult(&base::SingleThreadTaskRunner::PostTask),
                 callback_task_runner_, FROM_HERE,
                 base::Bind(&LottiePlayer::OnComplete, base::AsWeakPtr(this)));
  properties_.onloop_callback =
      base::Bind(base::IgnoreResult(&base::SingleThreadTaskRunner::PostTask),
                 callback_task_runner_, FROM_HERE,
                 base::Bind(&LottiePlayer::OnLoop, base::AsWeakPtr(this)));
  properties_.onenterframe_callback = base::Bind(
      &LottiePlayer::CallOnEnterFrame, callback_task_runner_,
      base::Bind(&LottiePlayer::OnEnterFrame, base::AsWeakPtr(this)));
  properties_.onfreeze_callback =
      base::Bind(base::IgnoreResult(&base::SingleThreadTaskRunner::PostTask),
                 callback_task_runner_, FROM_HERE,
                 base::Bind(&LottiePlayer::OnFreeze, base::AsWeakPtr(this)));
  properties_.onunfreeze_callback =
      base::Bind(base::IgnoreResult(&base::SingleThreadTaskRunner::PostTask),
                 callback_task_runner_, FROM_HERE,
                 base::Bind(&LottiePlayer::OnUnfreeze, base::AsWeakPtr(this)));
}

void LottiePlayer::OnPlay() { ScheduleEvent(base::Tokens::play()); }

void LottiePlayer::OnPause() { ScheduleEvent(base::Tokens::pause()); }

void LottiePlayer::OnStop() { ScheduleEvent(base::Tokens::stop()); }

void LottiePlayer::OnComplete() { ScheduleEvent(base::Tokens::complete()); }

void LottiePlayer::OnLoop() { ScheduleEvent(base::Tokens::loop()); }

void LottiePlayer::OnEnterFrame(double frame, double seeker) {
  LottieFrameCustomEventDetail detail;
  detail.set_frame(frame);
  detail.set_seeker(seeker);

  scoped_refptr<LottieFrameCustomEvent> lottie_frame_custom_event =
      new LottieFrameCustomEvent("frame");
  lottie_frame_custom_event->set_detail(detail);
  lottie_frame_custom_event->set_target(this);
  event_queue_.Enqueue(lottie_frame_custom_event);
}

void LottiePlayer::CallOnEnterFrame(
    scoped_refptr<base::SingleThreadTaskRunner> callback_task_runner,
    base::Callback<void(double, double)> enter_frame_callback, double frame,
    double seeker) {
  callback_task_runner->PostTask(
      FROM_HERE, base::Bind(enter_frame_callback, frame, seeker));
}

void LottiePlayer::OnFreeze() {
  if (properties_.FreezeAnimationState()) {
    ScheduleEvent(base::Tokens::freeze());
    UpdateLottieObjects();
  }
}

void LottiePlayer::OnUnfreeze() {
  if (properties_.UnfreezeAnimationState()) {
    ScheduleEvent(base::Tokens::play());
    UpdateLottieObjects();
  }
}

}  // namespace dom
}  // namespace cobalt
