// Copyright 2014 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/wm/test_session_state_animator.h"

#include <utility>
#include <vector>

#include "base/barrier_closure.h"
#include "base/bind.h"
#include "base/stl_util.h"

namespace ash {

namespace {
// A no-op callback that can be used when managing an animation that didn't
// actually have a callback given.
void DummyCallback() {}
}  // namespace

const SessionStateAnimator::Container
    TestSessionStateAnimator::kAllContainers[] = {
        SessionStateAnimator::WALLPAPER,
        SessionStateAnimator::SHELF,
        SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
        SessionStateAnimator::LOCK_SCREEN_WALLPAPER,
        SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
        SessionStateAnimator::LOCK_SCREEN_RELATED_CONTAINERS,
        SessionStateAnimator::ROOT_CONTAINER};

// A simple SessionStateAnimator::AnimationSequence that tracks the number of
// attached sequences.  The callback will be invoked if all animations complete
// successfully.
class TestSessionStateAnimator::AnimationSequence
    : public SessionStateAnimator::AnimationSequence {
 public:
  AnimationSequence(base::OnceClosure callback,
                    TestSessionStateAnimator* animator)
      : SessionStateAnimator::AnimationSequence(std::move(callback)),
        sequence_count_(0),
        sequence_aborted_(false),
        animator_(animator) {}

  ~AnimationSequence() override = default;

  virtual void SequenceAttached() { ++sequence_count_; }

  // Notify the sequence that is has completed.
  virtual void SequenceFinished(bool successfully) {
    DCHECK_GT(sequence_count_, 0);
    --sequence_count_;
    sequence_aborted_ |= !successfully;
    if (sequence_count_ == 0) {
      if (sequence_aborted_)
        OnAnimationAborted();
      else
        OnAnimationCompleted();
    }
  }

  // ash::SessionStateAnimator::AnimationSequence:
  void StartAnimation(int container_mask,
                      AnimationType type,
                      AnimationSpeed speed) override {
    animator_->StartAnimationInSequence(container_mask, type, speed, this);
  }

 private:
  // Tracks the number of contained animations.
  int sequence_count_;

  // True if the sequence was aborted.
  bool sequence_aborted_;

  // The TestSessionAnimator that created this.  Not owned.
  TestSessionStateAnimator* animator_;

  DISALLOW_COPY_AND_ASSIGN(AnimationSequence);
};

TestSessionStateAnimator::ActiveAnimation::ActiveAnimation(
    int animation_epoch,
    base::TimeDelta duration,
    SessionStateAnimator::Container container,
    AnimationType type,
    AnimationSpeed speed,
    base::Closure success_callback,
    base::Closure failed_callback)
    : animation_epoch(animation_epoch),
      remaining_duration(duration),
      container(container),
      type(type),
      speed(speed),
      success_callback(success_callback),
      failed_callback(failed_callback) {}

TestSessionStateAnimator::ActiveAnimation::ActiveAnimation(
    const ActiveAnimation& other) = default;

TestSessionStateAnimator::ActiveAnimation::~ActiveAnimation() = default;

TestSessionStateAnimator::TestSessionStateAnimator()
    : last_animation_epoch_(0), is_wallpaper_hidden_(false) {}

TestSessionStateAnimator::~TestSessionStateAnimator() {
  CompleteAllAnimations(false);
}

void TestSessionStateAnimator::ResetAnimationEpoch() {
  CompleteAllAnimations(false);
  last_animation_epoch_ = 0;
}

void TestSessionStateAnimator::Advance(const base::TimeDelta& duration) {
  for (ActiveAnimationsMap::iterator container_iter =
           active_animations_.begin();
       container_iter != active_animations_.end(); ++container_iter) {
    AnimationList::iterator animation_iter = (*container_iter).second.begin();
    while (animation_iter != (*container_iter).second.end()) {
      ActiveAnimation& active_animation = *animation_iter;
      active_animation.remaining_duration -= duration;
      if (active_animation.remaining_duration <= base::TimeDelta()) {
        active_animation.success_callback.Run();
        animation_iter = (*container_iter).second.erase(animation_iter);
      } else {
        ++animation_iter;
      }
    }
  }
}

void TestSessionStateAnimator::CompleteAnimations(int animation_epoch,
                                                  bool completed_successfully) {
  for (ActiveAnimationsMap::iterator container_iter =
           active_animations_.begin();
       container_iter != active_animations_.end(); ++container_iter) {
    AnimationList::iterator animation_iter = (*container_iter).second.begin();
    while (animation_iter != (*container_iter).second.end()) {
      ActiveAnimation active_animation = *animation_iter;
      if (active_animation.animation_epoch <= animation_epoch) {
        if (completed_successfully)
          active_animation.success_callback.Run();
        else
          active_animation.failed_callback.Run();
        animation_iter = (*container_iter).second.erase(animation_iter);
      } else {
        ++animation_iter;
      }
    }
  }
}

void TestSessionStateAnimator::CompleteAllAnimations(
    bool completed_successfully) {
  CompleteAnimations(last_animation_epoch_, completed_successfully);
}

bool TestSessionStateAnimator::IsContainerAnimated(
    SessionStateAnimator::Container container,
    SessionStateAnimator::AnimationType type) const {
  ActiveAnimationsMap::const_iterator container_iter =
      active_animations_.find(container);
  if (container_iter != active_animations_.end()) {
    for (AnimationList::const_iterator animation_iter =
             (*container_iter).second.begin();
         animation_iter != (*container_iter).second.end(); ++animation_iter) {
      const ActiveAnimation& active_animation = *animation_iter;
      if (active_animation.type == type)
        return true;
    }
  }
  return false;
}

bool TestSessionStateAnimator::AreContainersAnimated(
    int container_mask,
    SessionStateAnimator::AnimationType type) const {
  for (size_t i = 0; i < base::size(kAllContainers); ++i) {
    if (container_mask & kAllContainers[i] &&
        !IsContainerAnimated(kAllContainers[i], type)) {
      return false;
    }
  }
  return true;
}

size_t TestSessionStateAnimator::GetAnimationCount() const {
  size_t count = 0;
  for (ActiveAnimationsMap::const_iterator container_iter =
           active_animations_.begin();
       container_iter != active_animations_.end(); ++container_iter) {
    count += (*container_iter).second.size();
  }
  return count;
}

void TestSessionStateAnimator::StartAnimation(int container_mask,
                                              AnimationType type,
                                              AnimationSpeed speed) {
  ++last_animation_epoch_;
  for (size_t i = 0; i < base::size(kAllContainers); ++i) {
    if (container_mask & kAllContainers[i]) {
      // Use a dummy no-op callback because one isn't required by the client
      // but one is required when completing or aborting animations.
      base::Closure callback = base::Bind(&DummyCallback);
      AddAnimation(kAllContainers[i], type, speed, callback, callback);
    }
  }
}

void TestSessionStateAnimator::StartAnimationWithCallback(
    int container_mask,
    AnimationType type,
    AnimationSpeed speed,
    base::OnceClosure callback) {
  ++last_animation_epoch_;

  int container_count = 0;
  for (size_t i = 0; i < base::size(kAllContainers); ++i) {
    if (container_mask & kAllContainers[i])
      ++container_count;
  }

  base::RepeatingClosure completion_callback =
      base::BarrierClosure(container_count, std::move(callback));
  for (size_t i = 0; i < base::size(kAllContainers); ++i) {
    if (container_mask & kAllContainers[i]) {
      // ash::SessionStateAnimatorImpl invokes the callback whether or not the
      // animation was completed successfully or not.
      AddAnimation(kAllContainers[i], type, speed, completion_callback,
                   completion_callback);
    }
  }
}

ash::SessionStateAnimator::AnimationSequence*
TestSessionStateAnimator::BeginAnimationSequence(base::OnceClosure callback) {
  return new AnimationSequence(std::move(callback), this);
}

bool TestSessionStateAnimator::IsWallpaperHidden() const {
  return is_wallpaper_hidden_;
}

void TestSessionStateAnimator::ShowWallpaper() {
  is_wallpaper_hidden_ = false;
}

void TestSessionStateAnimator::HideWallpaper() {
  is_wallpaper_hidden_ = true;
}

void TestSessionStateAnimator::StartAnimationInSequence(
    int container_mask,
    AnimationType type,
    AnimationSpeed speed,
    AnimationSequence* animation_sequence) {
  ++last_animation_epoch_;
  for (size_t i = 0; i < base::size(kAllContainers); ++i) {
    if (container_mask & kAllContainers[i]) {
      base::Closure success_callback =
          base::Bind(&AnimationSequence::SequenceFinished,
                     base::Unretained(animation_sequence), true);
      base::Closure failed_callback =
          base::Bind(&AnimationSequence::SequenceFinished,
                     base::Unretained(animation_sequence), false);
      animation_sequence->SequenceAttached();
      AddAnimation(kAllContainers[i], type, speed, success_callback,
                   failed_callback);
    }
  }
}

void TestSessionStateAnimator::AddAnimation(
    SessionStateAnimator::Container container,
    AnimationType type,
    AnimationSpeed speed,
    base::Closure success_callback,
    base::Closure failed_callback) {
  base::TimeDelta duration = GetDuration(speed);
  ActiveAnimation active_animation(last_animation_epoch_, duration, container,
                                   type, speed, success_callback,
                                   failed_callback);
  // This test double is limited to only have one animation active for a given
  // container at a time.
  AbortAnimation(container);
  active_animations_[container].push_back(active_animation);
}

void TestSessionStateAnimator::AbortAnimation(
    SessionStateAnimator::Container container) {
  ActiveAnimationsMap::iterator container_iter =
      active_animations_.find(container);
  if (container_iter != active_animations_.end()) {
    AnimationList::iterator animation_iter = (*container_iter).second.begin();
    while (animation_iter != (*container_iter).second.end()) {
      ActiveAnimation active_animation = *animation_iter;
      active_animation.failed_callback.Run();
      animation_iter = (*container_iter).second.erase(animation_iter);
    }
  }
}

}  // namespace ash
