//===-- SBCommandInterpreterTest.cpp ------------------------===----------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===/

#include "gtest/gtest.h"

#include "lldb/API/SBCommandInterpreter.h"
#include "lldb/API/SBCommandReturnObject.h"
#include "lldb/API/SBDebugger.h"

#include <cstring>
#include <string>

using namespace lldb;

class SBCommandInterpreterTest : public testing::Test {
protected:
  void SetUp() override {
    SBDebugger::Initialize();
    m_dbg = SBDebugger::Create(/*source_init_files=*/false);
    m_interp = m_dbg.GetCommandInterpreter();
  }

  SBDebugger m_dbg;
  SBCommandInterpreter m_interp;
};

class DummyCommand : public SBCommandPluginInterface {
public:
  DummyCommand(const char *message) : m_message(message) {}

  bool DoExecute(SBDebugger dbg, char **command,
                 SBCommandReturnObject &result) {
    result.PutCString(m_message.c_str());
    result.SetStatus(eReturnStatusSuccessFinishResult);
    return result.Succeeded();
  }

private:
  std::string m_message;
};

TEST_F(SBCommandInterpreterTest, SingleWordCommand) {
  // We first test a command without autorepeat
  DummyCommand dummy("It worked");
  m_interp.AddCommand("dummy", &dummy, /*help=*/nullptr);
  {
    SBCommandReturnObject result;
    m_interp.HandleCommand("dummy", result, /*add_to_history=*/true);
    EXPECT_TRUE(result.Succeeded());
    EXPECT_STREQ(result.GetOutput(), "It worked\n");
  }
  {
    SBCommandReturnObject result;
    m_interp.HandleCommand("", result);
    EXPECT_FALSE(result.Succeeded());
    EXPECT_STREQ(result.GetError(), "error: No auto repeat.\n");
  }

  // Now we test a command with autorepeat
  m_interp.AddCommand("dummy_with_autorepeat", &dummy, /*help=*/nullptr,
                      /*syntax=*/nullptr, /*auto_repeat_command=*/nullptr);
  {
    SBCommandReturnObject result;
    m_interp.HandleCommand("dummy_with_autorepeat", result,
                           /*add_to_history=*/true);
    EXPECT_TRUE(result.Succeeded());
    EXPECT_STREQ(result.GetOutput(), "It worked\n");
  }
  {
    SBCommandReturnObject result;
    m_interp.HandleCommand("", result);
    EXPECT_TRUE(result.Succeeded());
    EXPECT_STREQ(result.GetOutput(), "It worked\n");
  }
}

TEST_F(SBCommandInterpreterTest, MultiWordCommand) {
  auto command = m_interp.AddMultiwordCommand("multicommand", /*help=*/nullptr);
  // We first test a subcommand without autorepeat
  DummyCommand subcommand("It worked again");
  command.AddCommand("subcommand", &subcommand, /*help=*/nullptr);
  {
    SBCommandReturnObject result;
    m_interp.HandleCommand("multicommand subcommand", result,
                           /*add_to_history=*/true);
    EXPECT_TRUE(result.Succeeded());
    EXPECT_STREQ(result.GetOutput(), "It worked again\n");
  }
  {
    SBCommandReturnObject result;
    m_interp.HandleCommand("", result);
    EXPECT_FALSE(result.Succeeded());
    EXPECT_STREQ(result.GetError(), "error: No auto repeat.\n");
  }

  // We first test a subcommand with autorepeat
  command.AddCommand("subcommand_with_autorepeat", &subcommand,
                     /*help=*/nullptr, /*syntax=*/nullptr,
                     /*auto_repeat_command=*/nullptr);
  {
    SBCommandReturnObject result;
    m_interp.HandleCommand("multicommand subcommand_with_autorepeat", result,
                           /*add_to_history=*/true);
    EXPECT_TRUE(result.Succeeded());
    EXPECT_STREQ(result.GetOutput(), "It worked again\n");
  }
  {
    SBCommandReturnObject result;
    m_interp.HandleCommand("", result);
    EXPECT_TRUE(result.Succeeded());
    EXPECT_STREQ(result.GetOutput(), "It worked again\n");
  }

  DummyCommand subcommand2("It worked again 2");
  // We now test a subcommand with autorepeat of the command name
  command.AddCommand(
      "subcommand_with_custom_autorepeat", &subcommand2, /*help=*/nullptr,
      /*syntax=*/nullptr,
      /*auto_repeat_command=*/"multicommand subcommand_with_autorepeat");
  {
    SBCommandReturnObject result;
    m_interp.HandleCommand("multicommand subcommand_with_custom_autorepeat",
                           result, /*add_to_history=*/true);
    EXPECT_TRUE(result.Succeeded());
    EXPECT_STREQ(result.GetOutput(), "It worked again 2\n");
  }
  {
    SBCommandReturnObject result;
    m_interp.HandleCommand("", result);
    EXPECT_TRUE(result.Succeeded());
    EXPECT_STREQ(result.GetOutput(), "It worked again\n");
  }
}
