// Copyright 2018 The Fuchsia 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 "src/developer/debug/zxdb/console/actions.h"

#include <gtest/gtest.h>

#include "src/developer/debug/shared/platform_message_loop.h"
#include "src/developer/debug/zxdb/client/session.h"
#include "src/developer/debug/zxdb/common/test_with_loop.h"
#include "src/developer/debug/zxdb/console/console_impl.h"
#include "src/lib/fxl/strings/string_printf.h"

namespace zxdb {

namespace {

using debug::MessageLoop;

#define STOP_MESSAGE_LOOP() \
  MessageLoop::Current()->PostTask(FROM_HERE, []() { MessageLoop::Current()->QuitNow(); })

// We override the Console in order to be able to override the dispatch
// function
class ConsoleTest : public ConsoleImpl {
 public:
  ConsoleTest(Session* session) : ConsoleImpl(session) {}

  void ProcessInputLine(const std::string& line, CommandCallback callback,
                        bool add_to_history) override {
    // We update the info
    calls.push_back(line);
    if (callback) {
      callback(errors_to_run[call_count]);
    }
    call_count++;
  }

  std::vector<std::string> calls;
  std::vector<Err> errors_to_run;
  size_t call_count = 0;
};

class ActionsTest : public TestWithLoop {
 protected:
  ActionsTest() {
    session = std::make_unique<Session>();
    console = std::make_unique<ConsoleTest>(session.get());
  }

  std::unique_ptr<Session> session;
  std::unique_ptr<ConsoleTest> console;
};

}  // namespace

using debug::MessageLoop;

TEST_F(ActionsTest, ScriptFile) {
  // We expect 3 calls
  console->errors_to_run = {Err(), Err(), Err()};
  // Setup the mock contents
  std::vector<std::string> mock_commands = {"help", "connect 192.168.0.1 2345", "break main",
                                            "run /path/to/binary"};
  std::stringstream ss;
  ss << mock_commands[0] << "\n" << mock_commands[1] << "\n" << mock_commands[2];
  std::string mock_contents = ss.str();

  auto actions = CommandsToActions(mock_contents);

  ASSERT_EQ(actions.size(), 3u);
  EXPECT_EQ(actions[0].name(), mock_commands[0]);
  EXPECT_EQ(actions[1].name(), mock_commands[1]);
  EXPECT_EQ(actions[2].name(), mock_commands[2]);

  Err callback_err("FAIL");
  auto callback = [&](Err err) {
    callback_err = err;
    STOP_MESSAGE_LOOP();
  };
  // The callback mechanism depends on a global ActionFlow
  ActionFlow& flow = ActionFlow::Singleton();
  flow.Clear();
  flow.ScheduleActions(std::move(actions), session.get(), console.get(), callback);
  loop().Run();

  EXPECT_FALSE(callback_err.has_error()) << callback_err.msg();

  ASSERT_EQ(console->calls.size(), 3u);
  EXPECT_EQ(console->calls[0], mock_commands[0]);
  EXPECT_EQ(console->calls[1], mock_commands[1]);
  EXPECT_EQ(console->calls[2], mock_commands[2]);

  ASSERT_EQ(flow.callbacks().size(), 3u);
  EXPECT_FALSE(flow.callbacks()[0].has_error());
  EXPECT_FALSE(flow.callbacks()[1].has_error());
  EXPECT_FALSE(flow.callbacks()[2].has_error());
}

TEST_F(ActionsTest, ScriptFileWithFailure) {
  // We expect an error
  console->errors_to_run = {Err(), Err("ERROR"), Err()};
  // Setup the mock contents
  std::vector<std::string> mock_commands = {"help", "connect 192.168.0.1 2345",
                                            "run /path/to/binary"};
  std::stringstream ss;
  ss << mock_commands[0] << "\n" << mock_commands[1] << "\n" << mock_commands[2];
  std::string mock_contents = ss.str();

  auto actions = CommandsToActions(mock_contents);

  ASSERT_EQ(actions.size(), 3u);
  EXPECT_EQ(actions[0].name(), mock_commands[0]);
  EXPECT_EQ(actions[1].name(), mock_commands[1]);
  EXPECT_EQ(actions[2].name(), mock_commands[2]);

  Err callback_err("FAIL");
  auto callback = [&](Err err) {
    callback_err = err;
    STOP_MESSAGE_LOOP();
  };

  // The callback mechanism depends on a global ActionFlow
  ActionFlow& flow = ActionFlow::Singleton();
  flow.Clear();
  flow.ScheduleActions(std::move(actions), session.get(), console.get(), callback);
  loop().Run();

  // The error callback was called
  EXPECT_TRUE(callback_err.has_error());

  // The second call fails
  ASSERT_EQ(console->calls.size(), 2u);
  EXPECT_EQ(console->calls[0], mock_commands[0]);
  EXPECT_EQ(console->calls[1], mock_commands[1]);

  ASSERT_EQ(flow.callbacks().size(), 2u);
  EXPECT_FALSE(flow.callbacks()[0].has_error());
  EXPECT_TRUE(flow.callbacks()[1].has_error());
}

}  // namespace zxdb
