/*
 * Copyright (C) 2008 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "core/svg/animation/SMILTimeContainer.h"

#include "core/animation/AnimationClock.h"
#include "core/animation/DocumentTimeline.h"
#include "core/dom/ElementTraversal.h"
#include "core/frame/FrameView.h"
#include "core/frame/Settings.h"
#include "core/frame/UseCounter.h"
#include "core/svg/SVGSVGElement.h"
#include "core/svg/animation/SMILTime.h"
#include "core/svg/animation/SVGSMILElement.h"
#include <algorithm>

namespace blink {

static const double initialFrameDelay = 0.025;
static const double animationPolicyOnceDuration = 3.000;

SMILTimeContainer::SMILTimeContainer(SVGSVGElement& owner)
    : m_presentationTime(0),
      m_referenceTime(0),
      m_frameSchedulingState(Idle),
      m_started(false),
      m_paused(false),
      m_documentOrderIndexesDirty(false),
      m_wakeupTimer(this, &SMILTimeContainer::wakeupTimerFired),
      m_animationPolicyOnceTimer(this,
                                 &SMILTimeContainer::animationPolicyTimerFired),
      m_ownerSVGElement(&owner)
#if ENABLE(ASSERT)
      ,
      m_preventScheduledAnimationsChanges(false)
#endif
{
}

SMILTimeContainer::~SMILTimeContainer() {
  cancelAnimationFrame();
  cancelAnimationPolicyTimer();
  ASSERT(!m_wakeupTimer.isActive());
#if ENABLE(ASSERT)
  ASSERT(!m_preventScheduledAnimationsChanges);
#endif
}

void SMILTimeContainer::schedule(SVGSMILElement* animation,
                                 SVGElement* target,
                                 const QualifiedName& attributeName) {
  ASSERT(animation->timeContainer() == this);
  ASSERT(target);
  ASSERT(animation->hasValidAttributeName());
  ASSERT(animation->hasValidAttributeType());
  ASSERT(animation->inActiveDocument());

#if ENABLE(ASSERT)
  ASSERT(!m_preventScheduledAnimationsChanges);
#endif

  ElementAttributePair key(target, attributeName);
  Member<AnimationsLinkedHashSet>& scheduled =
      m_scheduledAnimations.add(key, nullptr).storedValue->value;
  if (!scheduled)
    scheduled = new AnimationsLinkedHashSet;
  ASSERT(!scheduled->contains(animation));
  scheduled->add(animation);

  SMILTime nextFireTime = animation->nextProgressTime();
  if (nextFireTime.isFinite())
    notifyIntervalsChanged();
}

void SMILTimeContainer::unschedule(SVGSMILElement* animation,
                                   SVGElement* target,
                                   const QualifiedName& attributeName) {
  ASSERT(animation->timeContainer() == this);

#if ENABLE(ASSERT)
  ASSERT(!m_preventScheduledAnimationsChanges);
#endif

  ElementAttributePair key(target, attributeName);
  GroupedAnimationsMap::iterator it = m_scheduledAnimations.find(key);
  ASSERT(it != m_scheduledAnimations.end());
  AnimationsLinkedHashSet* scheduled = it->value.get();
  ASSERT(scheduled);
  AnimationsLinkedHashSet::iterator itAnimation = scheduled->find(animation);
  ASSERT(itAnimation != scheduled->end());
  scheduled->remove(itAnimation);

  if (scheduled->isEmpty())
    m_scheduledAnimations.remove(it);
}

bool SMILTimeContainer::hasAnimations() const {
  return !m_scheduledAnimations.isEmpty();
}

bool SMILTimeContainer::hasPendingSynchronization() const {
  return m_frameSchedulingState == SynchronizeAnimations &&
         m_wakeupTimer.isActive() && !m_wakeupTimer.nextFireInterval();
}

void SMILTimeContainer::notifyIntervalsChanged() {
  if (!isStarted())
    return;
  // Schedule updateAnimations() to be called asynchronously so multiple
  // intervals can change with updateAnimations() only called once at the end.
  if (hasPendingSynchronization())
    return;
  cancelAnimationFrame();
  scheduleWakeUp(0, SynchronizeAnimations);
}

double SMILTimeContainer::elapsed() const {
  if (!isStarted())
    return 0;

  if (isPaused())
    return m_presentationTime;

  return m_presentationTime +
         (document().timeline().currentTimeInternal() - m_referenceTime);
}

void SMILTimeContainer::synchronizeToDocumentTimeline() {
  m_referenceTime = document().timeline().currentTimeInternal();
}

bool SMILTimeContainer::isPaused() const {
  // If animation policy is "none", the timeline is always paused.
  return m_paused || animationPolicy() == ImageAnimationPolicyNoAnimation;
}

bool SMILTimeContainer::isStarted() const {
  return m_started;
}

bool SMILTimeContainer::isTimelineRunning() const {
  return isStarted() && !isPaused();
}

void SMILTimeContainer::start() {
  RELEASE_ASSERT(!isStarted());

  if (!document().isActive())
    return;

  if (!handleAnimationPolicy(RestartOnceTimerIfNotPaused))
    return;

  // Sample the document timeline to get a time reference for the "presentation
  // time".
  synchronizeToDocumentTimeline();
  m_started = true;

  // If the "presentation time" is non-zero, the timeline was modified via
  // setElapsed() before the document began.  In this case pass on
  // 'seekToTime=true' to updateAnimations() to issue a seek.
  SMILTime earliestFireTime =
      updateAnimations(m_presentationTime, m_presentationTime ? true : false);
  if (!canScheduleFrame(earliestFireTime))
    return;
  // If the timeline is running, and there are pending animation updates,
  // always perform the first update after the timeline was started using
  // the wake-up mechanism.
  double delayTime = earliestFireTime.value() - m_presentationTime;
  scheduleWakeUp(std::max(initialFrameDelay, delayTime), SynchronizeAnimations);
}

void SMILTimeContainer::pause() {
  if (!handleAnimationPolicy(CancelOnceTimer))
    return;
  DCHECK(!isPaused());

  if (isStarted()) {
    m_presentationTime = elapsed();
    cancelAnimationFrame();
  }
  // Update the flag after sampling elapsed().
  m_paused = true;
}

void SMILTimeContainer::resume() {
  if (!handleAnimationPolicy(RestartOnceTimer))
    return;
  DCHECK(isPaused());

  m_paused = false;

  if (!isStarted())
    return;

  synchronizeToDocumentTimeline();
  scheduleWakeUp(0, SynchronizeAnimations);
}

void SMILTimeContainer::setElapsed(double elapsed) {
  m_presentationTime = elapsed;

  // If the document hasn't finished loading, |m_presentationTime| will be
  // used as the start time to seek to once it's possible.
  if (!isStarted())
    return;

  if (!handleAnimationPolicy(RestartOnceTimerIfNotPaused))
    return;

  cancelAnimationFrame();

  if (!isPaused())
    synchronizeToDocumentTimeline();

#if ENABLE(ASSERT)
  m_preventScheduledAnimationsChanges = true;
#endif
  for (const auto& entry : m_scheduledAnimations) {
    if (!entry.key.first)
      continue;

    AnimationsLinkedHashSet* scheduled = entry.value.get();
    for (SVGSMILElement* element : *scheduled)
      element->reset();
  }
#if ENABLE(ASSERT)
  m_preventScheduledAnimationsChanges = false;
#endif

  updateAnimationsAndScheduleFrameIfNeeded(elapsed, true);
}

void SMILTimeContainer::scheduleAnimationFrame(double delayTime) {
  DCHECK(std::isfinite(delayTime));
  DCHECK(isTimelineRunning());
  DCHECK(!m_wakeupTimer.isActive());

  if (delayTime < AnimationTimeline::s_minimumDelay) {
    serviceOnNextFrame();
  } else {
    scheduleWakeUp(delayTime - AnimationTimeline::s_minimumDelay,
                   FutureAnimationFrame);
  }
}

void SMILTimeContainer::cancelAnimationFrame() {
  m_frameSchedulingState = Idle;
  m_wakeupTimer.stop();
}

void SMILTimeContainer::scheduleWakeUp(
    double delayTime,
    FrameSchedulingState frameSchedulingState) {
  ASSERT(frameSchedulingState == SynchronizeAnimations ||
         frameSchedulingState == FutureAnimationFrame);
  m_wakeupTimer.startOneShot(delayTime, BLINK_FROM_HERE);
  m_frameSchedulingState = frameSchedulingState;
}

void SMILTimeContainer::wakeupTimerFired(TimerBase*) {
  ASSERT(m_frameSchedulingState == SynchronizeAnimations ||
         m_frameSchedulingState == FutureAnimationFrame);
  if (m_frameSchedulingState == FutureAnimationFrame) {
    ASSERT(isTimelineRunning());
    m_frameSchedulingState = Idle;
    serviceOnNextFrame();
  } else {
    m_frameSchedulingState = Idle;
    updateAnimationsAndScheduleFrameIfNeeded(elapsed());
  }
}

void SMILTimeContainer::scheduleAnimationPolicyTimer() {
  m_animationPolicyOnceTimer.startOneShot(animationPolicyOnceDuration,
                                          BLINK_FROM_HERE);
}

void SMILTimeContainer::cancelAnimationPolicyTimer() {
  if (m_animationPolicyOnceTimer.isActive())
    m_animationPolicyOnceTimer.stop();
}

void SMILTimeContainer::animationPolicyTimerFired(TimerBase*) {
  pause();
}

ImageAnimationPolicy SMILTimeContainer::animationPolicy() const {
  Settings* settings = document().settings();
  if (!settings)
    return ImageAnimationPolicyAllowed;

  return settings->imageAnimationPolicy();
}

bool SMILTimeContainer::handleAnimationPolicy(
    AnimationPolicyOnceAction onceAction) {
  ImageAnimationPolicy policy = animationPolicy();
  // If the animation policy is "none", control is not allowed.
  // returns false to exit flow.
  if (policy == ImageAnimationPolicyNoAnimation)
    return false;
  // If the animation policy is "once",
  if (policy == ImageAnimationPolicyAnimateOnce) {
    switch (onceAction) {
      case RestartOnceTimerIfNotPaused:
        if (isPaused())
          break;
      /* fall through */
      case RestartOnceTimer:
        scheduleAnimationPolicyTimer();
        break;
      case CancelOnceTimer:
        cancelAnimationPolicyTimer();
        break;
    }
  }
  if (policy == ImageAnimationPolicyAllowed) {
    // When the SVG owner element becomes detached from its document,
    // the policy defaults to ImageAnimationPolicyAllowed; there's
    // no way back. If the policy had been "once" prior to that,
    // ensure cancellation of its timer.
    if (onceAction == CancelOnceTimer)
      cancelAnimationPolicyTimer();
  }
  return true;
}

void SMILTimeContainer::updateDocumentOrderIndexes() {
  unsigned timingElementCount = 0;
  for (SVGSMILElement& element :
       Traversal<SVGSMILElement>::descendantsOf(ownerSVGElement()))
    element.setDocumentOrderIndex(timingElementCount++);
  m_documentOrderIndexesDirty = false;
}

struct PriorityCompare {
  PriorityCompare(double elapsed) : m_elapsed(elapsed) {}
  bool operator()(const Member<SVGSMILElement>& a,
                  const Member<SVGSMILElement>& b) {
    // FIXME: This should also consider possible timing relations between the
    // elements.
    SMILTime aBegin = a->intervalBegin();
    SMILTime bBegin = b->intervalBegin();
    // Frozen elements need to be prioritized based on their previous interval.
    aBegin = a->isFrozen() && m_elapsed < aBegin ? a->previousIntervalBegin()
                                                 : aBegin;
    bBegin = b->isFrozen() && m_elapsed < bBegin ? b->previousIntervalBegin()
                                                 : bBegin;
    if (aBegin == bBegin)
      return a->documentOrderIndex() < b->documentOrderIndex();
    return aBegin < bBegin;
  }
  double m_elapsed;
};

SVGSVGElement& SMILTimeContainer::ownerSVGElement() const {
  return *m_ownerSVGElement;
}

Document& SMILTimeContainer::document() const {
  return ownerSVGElement().document();
}

void SMILTimeContainer::serviceOnNextFrame() {
  if (document().view()) {
    document().view()->scheduleAnimation();
    m_frameSchedulingState = AnimationFrame;
  }
}

void SMILTimeContainer::serviceAnimations() {
  if (m_frameSchedulingState != AnimationFrame)
    return;

  m_frameSchedulingState = Idle;
  updateAnimationsAndScheduleFrameIfNeeded(elapsed());
}

bool SMILTimeContainer::canScheduleFrame(SMILTime earliestFireTime) const {
  // If there's synchronization pending (most likely due to syncbases), then
  // let that complete first before attempting to schedule a frame.
  if (hasPendingSynchronization())
    return false;
  if (!isTimelineRunning())
    return false;
  return earliestFireTime.isFinite();
}

void SMILTimeContainer::updateAnimationsAndScheduleFrameIfNeeded(
    double elapsed,
    bool seekToTime) {
  if (!document().isActive())
    return;

  SMILTime earliestFireTime = updateAnimations(elapsed, seekToTime);
  if (!canScheduleFrame(earliestFireTime))
    return;
  double delayTime = earliestFireTime.value() - elapsed;
  scheduleAnimationFrame(delayTime);
}

SMILTime SMILTimeContainer::updateAnimations(double elapsed, bool seekToTime) {
  ASSERT(document().isActive());
  SMILTime earliestFireTime = SMILTime::unresolved();

#if ENABLE(ASSERT)
  // This boolean will catch any attempts to schedule/unschedule
  // scheduledAnimations during this critical section.  Similarly, any elements
  // removed will unschedule themselves, so this will catch modification of
  // animationsToApply.
  m_preventScheduledAnimationsChanges = true;
#endif

  if (m_documentOrderIndexesDirty)
    updateDocumentOrderIndexes();

  HeapHashSet<ElementAttributePair> invalidKeys;
  using AnimationsVector = HeapVector<Member<SVGSMILElement>>;
  AnimationsVector animationsToApply;
  AnimationsVector scheduledAnimationsInSameGroup;
  for (const auto& entry : m_scheduledAnimations) {
    if (!entry.key.first || entry.value->isEmpty()) {
      invalidKeys.add(entry.key);
      continue;
    }

    // Sort according to priority. Elements with later begin time have higher
    // priority.  In case of a tie, document order decides.
    // FIXME: This should also consider timing relationships between the
    // elements. Dependents have higher priority.
    copyToVector(*entry.value, scheduledAnimationsInSameGroup);
    std::sort(scheduledAnimationsInSameGroup.begin(),
              scheduledAnimationsInSameGroup.end(), PriorityCompare(elapsed));

    AnimationsVector sandwich;
    for (const auto& itAnimation : scheduledAnimationsInSameGroup) {
      SVGSMILElement* animation = itAnimation.get();
      ASSERT(animation->timeContainer() == this);
      ASSERT(animation->targetElement());
      ASSERT(animation->hasValidAttributeName());
      ASSERT(animation->hasValidAttributeType());

      // This will calculate the contribution from the animation and update
      // timing.
      if (animation->progress(elapsed, seekToTime)) {
        sandwich.append(animation);
      } else {
        animation->clearAnimatedType();
      }

      SMILTime nextFireTime = animation->nextProgressTime();
      if (nextFireTime.isFinite())
        earliestFireTime = std::min(nextFireTime, earliestFireTime);
    }

    if (!sandwich.isEmpty()) {
      // Results are accumulated to the first animation that animates and
      // contributes to a particular element/attribute pair.
      // Only reset the animated type to the base value once for
      // the lowest priority animation that animates and
      // contributes to a particular element/attribute pair.
      SVGSMILElement* resultElement = sandwich.first();
      resultElement->resetAnimatedType();

      // Go through the sandwich from lowest prio to highest and generate
      // the animated value (if any.)
      for (const auto& animation : sandwich)
        animation->updateAnimatedValue(resultElement);

      animationsToApply.append(resultElement);
    }
  }
  m_scheduledAnimations.removeAll(invalidKeys);

  if (animationsToApply.isEmpty()) {
#if ENABLE(ASSERT)
    m_preventScheduledAnimationsChanges = false;
#endif
    return earliestFireTime;
  }

  UseCounter::count(&document(), UseCounter::SVGSMILAnimationAppliedEffect);

  std::sort(animationsToApply.begin(), animationsToApply.end(),
            PriorityCompare(elapsed));

  // Apply results to target elements.
  for (const auto& timedElement : animationsToApply)
    timedElement->applyResultsToTarget();

#if ENABLE(ASSERT)
  m_preventScheduledAnimationsChanges = false;
#endif

  for (const auto& timedElement : animationsToApply) {
    if (timedElement->isConnected() && timedElement->isSVGDiscardElement()) {
      SVGElement* targetElement = timedElement->targetElement();
      if (targetElement && targetElement->isConnected()) {
        targetElement->remove(IGNORE_EXCEPTION);
        DCHECK(!targetElement->isConnected());
      }

      if (timedElement->isConnected()) {
        timedElement->remove(IGNORE_EXCEPTION);
        DCHECK(!timedElement->isConnected());
      }
    }
  }
  return earliestFireTime;
}

void SMILTimeContainer::advanceFrameForTesting() {
  setElapsed(elapsed() + initialFrameDelay);
}

DEFINE_TRACE(SMILTimeContainer) {
  visitor->trace(m_scheduledAnimations);
  visitor->trace(m_ownerSVGElement);
}

}  // namespace blink
