// Copyright (c) 2009 The Chromium OS 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 <string>
#include <gtest/gtest.h>
#include "update_engine/action.h"
#include "update_engine/action_processor.h"

using std::string;

namespace chromeos_update_engine {

using chromeos_update_engine::ActionPipe;

class ActionProcessorTestAction;

template<>
class ActionTraits<ActionProcessorTestAction> {
 public:
  typedef string OutputObjectType;
  typedef string InputObjectType;
};

// This is a simple Action class for testing.
struct ActionProcessorTestAction : public Action<ActionProcessorTestAction> {
  typedef string InputObjectType;
  typedef string OutputObjectType;
  ActionPipe<string>* in_pipe() { return in_pipe_.get(); }
  ActionPipe<string>* out_pipe() { return out_pipe_.get(); }
  ActionProcessor* processor() { return processor_; }
  void PerformAction() {}
  void CompleteAction() {
    ASSERT_TRUE(processor());
    processor()->ActionComplete(this, kActionCodeSuccess);
  }
  string Type() const { return "ActionProcessorTestAction"; }
};

class ActionProcessorTest : public ::testing::Test { };

// This test creates two simple Actions and sends a message via an ActionPipe
// from one to the other.
TEST(ActionProcessorTest, SimpleTest) {
  ActionProcessorTestAction action;
  ActionProcessor action_processor;
  EXPECT_FALSE(action_processor.IsRunning());
  action_processor.EnqueueAction(&action);
  EXPECT_FALSE(action_processor.IsRunning());
  EXPECT_FALSE(action.IsRunning());
  action_processor.StartProcessing();
  EXPECT_TRUE(action_processor.IsRunning());
  EXPECT_TRUE(action.IsRunning());
  EXPECT_EQ(action_processor.current_action(), &action);
  action.CompleteAction();
  EXPECT_FALSE(action_processor.IsRunning());
  EXPECT_FALSE(action.IsRunning());
}

namespace {
class MyActionProcessorDelegate : public ActionProcessorDelegate {
 public:
  explicit MyActionProcessorDelegate(const ActionProcessor* processor)
      : processor_(processor),
        processing_done_called_(false),
        processing_stopped_called_(false),
        action_completed_called_(false),
        action_exit_code_(kActionCodeError) {}

  virtual void ProcessingDone(const ActionProcessor* processor,
                              ActionExitCode code) {
    EXPECT_EQ(processor_, processor);
    EXPECT_FALSE(processing_done_called_);
    processing_done_called_ = true;
  }
  virtual void ProcessingStopped(const ActionProcessor* processor) {
    EXPECT_EQ(processor_, processor);
    EXPECT_FALSE(processing_stopped_called_);
    processing_stopped_called_ = true;
  }
  virtual void ActionCompleted(ActionProcessor* processor,
                               AbstractAction* action,
                               ActionExitCode code) {
    EXPECT_EQ(processor_, processor);
    EXPECT_FALSE(action_completed_called_);
    action_completed_called_ = true;
    action_exit_code_ = code;
  }

  const ActionProcessor* processor_;
  bool processing_done_called_;
  bool processing_stopped_called_;
  bool action_completed_called_;
  ActionExitCode action_exit_code_;
};
}  // namespace {}

TEST(ActionProcessorTest, DelegateTest) {
  ActionProcessorTestAction action;
  ActionProcessor action_processor;
  MyActionProcessorDelegate delegate(&action_processor);
  action_processor.set_delegate(&delegate);

  action_processor.EnqueueAction(&action);
  action_processor.StartProcessing();
  action.CompleteAction();
  action_processor.set_delegate(NULL);
  EXPECT_TRUE(delegate.processing_done_called_);
  EXPECT_TRUE(delegate.action_completed_called_);
}

TEST(ActionProcessorTest, StopProcessingTest) {
  ActionProcessorTestAction action;
  ActionProcessor action_processor;
  MyActionProcessorDelegate delegate(&action_processor);
  action_processor.set_delegate(&delegate);

  action_processor.EnqueueAction(&action);
  action_processor.StartProcessing();
  action_processor.StopProcessing();
  action_processor.set_delegate(NULL);
  EXPECT_TRUE(delegate.processing_stopped_called_);
  EXPECT_FALSE(delegate.action_completed_called_);
  EXPECT_FALSE(action_processor.IsRunning());
  EXPECT_EQ(NULL, action_processor.current_action());
}

TEST(ActionProcessorTest, ChainActionsTest) {
  ActionProcessorTestAction action1, action2;
  ActionProcessor action_processor;
  action_processor.EnqueueAction(&action1);
  action_processor.EnqueueAction(&action2);
  action_processor.StartProcessing();
  EXPECT_EQ(&action1, action_processor.current_action());
  EXPECT_TRUE(action_processor.IsRunning());
  action1.CompleteAction();
  EXPECT_EQ(&action2, action_processor.current_action());
  EXPECT_TRUE(action_processor.IsRunning());
  action2.CompleteAction();
  EXPECT_EQ(NULL, action_processor.current_action());
  EXPECT_FALSE(action_processor.IsRunning());
}

TEST(ActionProcessorTest, DtorTest) {
  ActionProcessorTestAction action1, action2;
  {
    ActionProcessor action_processor;
    action_processor.EnqueueAction(&action1);
    action_processor.EnqueueAction(&action2);
    action_processor.StartProcessing();
  }
  EXPECT_EQ(NULL, action1.processor());
  EXPECT_FALSE(action1.IsRunning());
  EXPECT_EQ(NULL, action2.processor());
  EXPECT_FALSE(action2.IsRunning());
}

TEST(ActionProcessorTest, DefaultDelegateTest) {
  // Just make sure it doesn't crash
  ActionProcessorTestAction action;
  ActionProcessor action_processor;
  ActionProcessorDelegate delegate;
  action_processor.set_delegate(&delegate);

  action_processor.EnqueueAction(&action);
  action_processor.StartProcessing();
  action.CompleteAction();

  action_processor.EnqueueAction(&action);
  action_processor.StartProcessing();
  action_processor.StopProcessing();

  action_processor.set_delegate(NULL);
}

}  // namespace chromeos_update_engine
