// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/undo/undo_manager.h"

#include <memory>

#include "base/auto_reset.h"
#include "base/memory/raw_ptr.h"
#include "components/undo/undo_manager_observer.h"
#include "components/undo/undo_operation.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

std::vector<UndoOperation*> ConvertToRawPtrVector(
    const std::vector<std::unique_ptr<UndoOperation>>& args) {
  std::vector<UndoOperation*> args_rawptrs;
  for (auto i = args.begin(); i != args.end(); ++i)
    args_rawptrs.push_back(i->get());
  return args_rawptrs;
}

}  // namespace

// UndoManagerTestApi ----------------------------------------------------------

class UndoManagerTestApi {
 public:
  UndoManagerTestApi() = delete;
  UndoManagerTestApi(const UndoManagerTestApi&) = delete;
  UndoManagerTestApi& operator=(const UndoManagerTestApi&) = delete;

  // Returns all UndoOperations that are awaiting Undo or Redo.
  static std::vector<UndoOperation*> GetAllUndoOperations(
      const UndoManager& undo_manager);
};

std::vector<UndoOperation*> UndoManagerTestApi::GetAllUndoOperations(
    const UndoManager& undo_manager) {
  std::vector<UndoOperation*> result;
  for (size_t i = 0; i < undo_manager.undo_actions_.size(); ++i) {
    const std::vector<UndoOperation*> operations =
        ConvertToRawPtrVector(undo_manager.undo_actions_[i]->undo_operations());
    result.insert(result.end(), operations.begin(), operations.end());
  }
  for (size_t i = 0; i < undo_manager.redo_actions_.size(); ++i) {
    const std::vector<UndoOperation*> operations =
        ConvertToRawPtrVector(undo_manager.redo_actions_[i]->undo_operations());
    result.insert(result.end(), operations.begin(), operations.end());
  }
  // Ensure that if an Undo is in progress the UndoOperations part of that
  // UndoGroup are included in the returned set. This will ensure that any
  // changes (such as renumbering) will be applied to any potentially
  // unprocessed UndoOperations.
  if (undo_manager.undo_in_progress_action_) {
    const std::vector<UndoOperation*> operations = ConvertToRawPtrVector(
        undo_manager.undo_in_progress_action_->undo_operations());
    result.insert(result.end(), operations.begin(), operations.end());
  }

  return result;
}

namespace {

class TestUndoOperation;

// TestUndoService -------------------------------------------------------------

class TestUndoService {
 public:
  TestUndoService();
  ~TestUndoService();

  void Redo();
  void TriggerOperation();
  void RecordUndoCall();

  UndoManager undo_manager_;

  bool performing_redo_;

  int undo_operation_count_;
  int redo_operation_count_;
};

// TestUndoOperation -----------------------------------------------------------

class TestUndoOperation : public UndoOperation {
 public:
  explicit TestUndoOperation(TestUndoService* undo_service);

  TestUndoOperation(const TestUndoOperation&) = delete;
  TestUndoOperation& operator=(const TestUndoOperation&) = delete;

  ~TestUndoOperation() override;

  // UndoOperation:
  void Undo() override;
  int GetUndoLabelId() const override;
  int GetRedoLabelId() const override;

 private:
  raw_ptr<TestUndoService> undo_service_;
};

TestUndoOperation::TestUndoOperation(TestUndoService* undo_service)
      : undo_service_(undo_service) {
}

TestUndoOperation::~TestUndoOperation() {
}

void TestUndoOperation::Undo() {
  undo_service_->TriggerOperation();
  undo_service_->RecordUndoCall();
}

int TestUndoOperation::GetUndoLabelId() const {
  return 0;
}

int TestUndoOperation::GetRedoLabelId() const {
  return 0;
}

// TestUndoService -------------------------------------------------------------

TestUndoService::TestUndoService() : performing_redo_(false),
                                     undo_operation_count_(0),
                                     redo_operation_count_(0) {
}

TestUndoService::~TestUndoService() {
}

void TestUndoService::Redo() {
  base::AutoReset<bool> incoming_changes(&performing_redo_, true);
  undo_manager_.Redo();
}

void TestUndoService::TriggerOperation() {
  undo_manager_.AddUndoOperation(std::make_unique<TestUndoOperation>(this));
}

void TestUndoService::RecordUndoCall() {
  if (performing_redo_)
    ++redo_operation_count_;
  else
    ++undo_operation_count_;
}

// TestObserver ----------------------------------------------------------------

class TestObserver : public UndoManagerObserver {
 public:
  TestObserver() : state_change_count_(0) {}
  // Returns the number of state change callbacks

  TestObserver(const TestObserver&) = delete;
  TestObserver& operator=(const TestObserver&) = delete;

  int state_change_count() { return state_change_count_; }

  void OnUndoManagerStateChange() override { ++state_change_count_; }

 private:
  int state_change_count_;
};

// Tests -----------------------------------------------------------------------

TEST(UndoServiceTest, AddUndoActions) {
  TestUndoService undo_service;

  undo_service.TriggerOperation();
  undo_service.TriggerOperation();
  EXPECT_EQ(2U, undo_service.undo_manager_.undo_count());
  EXPECT_EQ(0U, undo_service.undo_manager_.redo_count());
}

TEST(UndoServiceTest, UndoMultipleActions) {
  TestUndoService undo_service;

  undo_service.TriggerOperation();
  undo_service.TriggerOperation();

  undo_service.undo_manager_.Undo();
  EXPECT_EQ(1U, undo_service.undo_manager_.undo_count());
  EXPECT_EQ(1U, undo_service.undo_manager_.redo_count());

  undo_service.undo_manager_.Undo();
  EXPECT_EQ(0U, undo_service.undo_manager_.undo_count());
  EXPECT_EQ(2U, undo_service.undo_manager_.redo_count());

  EXPECT_EQ(2, undo_service.undo_operation_count_);
  EXPECT_EQ(0, undo_service.redo_operation_count_);
}

TEST(UndoServiceTest, RedoAction) {
  TestUndoService undo_service;

  undo_service.TriggerOperation();

  undo_service.undo_manager_.Undo();
  EXPECT_EQ(0U, undo_service.undo_manager_.undo_count());
  EXPECT_EQ(1U, undo_service.undo_manager_.redo_count());

  undo_service.Redo();
  EXPECT_EQ(1U, undo_service.undo_manager_.undo_count());
  EXPECT_EQ(0U, undo_service.undo_manager_.redo_count());

  EXPECT_EQ(1, undo_service.undo_operation_count_);
  EXPECT_EQ(1, undo_service.redo_operation_count_);
}

TEST(UndoServiceTest, GroupActions) {
  TestUndoService undo_service;

  // Add two operations in a single action.
  undo_service.undo_manager_.StartGroupingActions();
  undo_service.TriggerOperation();
  undo_service.TriggerOperation();
  undo_service.undo_manager_.EndGroupingActions();

  // Check that only one action is created.
  EXPECT_EQ(1U, undo_service.undo_manager_.undo_count());
  EXPECT_EQ(0U, undo_service.undo_manager_.redo_count());

  undo_service.undo_manager_.Undo();
  EXPECT_EQ(0U, undo_service.undo_manager_.undo_count());
  EXPECT_EQ(1U, undo_service.undo_manager_.redo_count());

  undo_service.Redo();
  EXPECT_EQ(1U, undo_service.undo_manager_.undo_count());
  EXPECT_EQ(0U, undo_service.undo_manager_.redo_count());

  // Check that both operations were called in Undo and Redo.
  EXPECT_EQ(2, undo_service.undo_operation_count_);
  EXPECT_EQ(2, undo_service.redo_operation_count_);
}

TEST(UndoServiceTest, SuspendUndoTracking) {
  TestUndoService undo_service;

  undo_service.undo_manager_.SuspendUndoTracking();
  EXPECT_TRUE(undo_service.undo_manager_.IsUndoTrakingSuspended());

  undo_service.TriggerOperation();

  undo_service.undo_manager_.ResumeUndoTracking();
  EXPECT_FALSE(undo_service.undo_manager_.IsUndoTrakingSuspended());

  EXPECT_EQ(0U, undo_service.undo_manager_.undo_count());
  EXPECT_EQ(0U, undo_service.undo_manager_.redo_count());
}

TEST(UndoServiceTest, RedoEmptyAfterNewAction) {
  TestUndoService undo_service;

  undo_service.TriggerOperation();
  undo_service.undo_manager_.Undo();
  EXPECT_EQ(0U, undo_service.undo_manager_.undo_count());
  EXPECT_EQ(1U, undo_service.undo_manager_.redo_count());

  undo_service.TriggerOperation();
  EXPECT_EQ(1U, undo_service.undo_manager_.undo_count());
  EXPECT_EQ(0U, undo_service.undo_manager_.redo_count());
}

TEST(UndoServiceTest, GetAllUndoOperations) {
  TestUndoService undo_service;

  undo_service.TriggerOperation();

  undo_service.undo_manager_.StartGroupingActions();
  undo_service.TriggerOperation();
  undo_service.TriggerOperation();
  undo_service.undo_manager_.EndGroupingActions();

  undo_service.TriggerOperation();

  undo_service.undo_manager_.Undo();
  ASSERT_EQ(2U, undo_service.undo_manager_.undo_count());
  ASSERT_EQ(1U, undo_service.undo_manager_.redo_count());

  std::vector<UndoOperation*> all_operations =
      UndoManagerTestApi::GetAllUndoOperations(undo_service.undo_manager_);
  EXPECT_EQ(4U, all_operations.size());
}

TEST(UndoServiceTest, ObserverCallbacks) {
  TestObserver observer;
  TestUndoService undo_service;
  undo_service.undo_manager_.AddObserver(&observer);
  EXPECT_EQ(0, observer.state_change_count());

  undo_service.TriggerOperation();
  EXPECT_EQ(1, observer.state_change_count());

  undo_service.undo_manager_.StartGroupingActions();
  undo_service.TriggerOperation();
  undo_service.TriggerOperation();
  undo_service.undo_manager_.EndGroupingActions();
  EXPECT_EQ(2, observer.state_change_count());

  // There should be at least 1 observer callback for undo.
  undo_service.undo_manager_.Undo();
  int callback_count_after_undo = observer.state_change_count();
  EXPECT_GT(callback_count_after_undo, 2);

  // There should be at least 1 observer callback for redo.
  undo_service.undo_manager_.Redo();
  int callback_count_after_redo = observer.state_change_count();
  EXPECT_GT(callback_count_after_redo, callback_count_after_undo);

  undo_service.undo_manager_.RemoveObserver(&observer);
  undo_service.undo_manager_.Undo();
  EXPECT_EQ(callback_count_after_redo, observer.state_change_count());
}

} // namespace
