#include "mission/mission_enqueue.hpp"
#include "mission/mission_store.hpp"

#include <gtest/gtest.h>

#include <filesystem>

namespace {

std::filesystem::path fixtureMissionsPath()
{
  return std::filesystem::path(TEST_FIXTURE_DIR) / "missions.json";
}

lm::MissionStore makeStore()
{
  const auto dir = std::filesystem::temp_directory_path() / "lm_test_enqueue";
  std::filesystem::create_directories(dir);
  const auto path = dir / "missions.json";
  std::filesystem::copy_file(fixtureMissionsPath(), path, std::filesystem::copy_options::overwrite_existing);
  return lm::MissionStore(path);
}

}  // namespace

TEST(MissionEnqueue, NormalizeParametersFromMirArray)
{
  const nlohmann::json params = nlohmann::json::array({{{"id", "pos"}, {"value", "A1"}},
                                                       {{"key", "speed"}, {"value", 0.5}}});
  const nlohmann::json out = lm::MissionEnqueue::normalizeParameters(params);
  EXPECT_TRUE(out.is_object());
  EXPECT_EQ(out["pos"], "A1");
  EXPECT_EQ(out["speed"], 0.5);
}

TEST(MissionEnqueue, NormalizeParametersObjectPassthrough)
{
  const nlohmann::json params = {{"x", 1}};
  const nlohmann::json out = lm::MissionEnqueue::normalizeParameters(params);
  EXPECT_EQ(out, params);
}

TEST(MissionEnqueue, BuildPayloadFromMissionId)
{
  lm::MissionStore store = makeStore();
  nlohmann::json payload;
  std::string err;
  const nlohmann::json request = {{"mission_id", "testmission00001"}, {"priority", 3}, {"robot_id", "default"}};
  ASSERT_TRUE(lm::MissionEnqueue::buildPayload(store, request, payload, err)) << err;
  EXPECT_EQ(payload["mission"]["id"], "testmission00001");
  EXPECT_EQ(payload["priority"], 3);
  EXPECT_EQ(payload["robot_id"], "default");
}

TEST(MissionEnqueue, BuildPayloadMissingMissionFails)
{
  lm::MissionStore store = makeStore();
  nlohmann::json payload;
  std::string err;
  const nlohmann::json request = {{"mission_id", "does_not_exist"}};
  EXPECT_FALSE(lm::MissionEnqueue::buildPayload(store, request, payload, err));
  EXPECT_FALSE(err.empty());
}

TEST(MissionEnqueue, BuildPayloadRequiresMissionOrId)
{
  lm::MissionStore store = makeStore();
  nlohmann::json payload;
  std::string err;
  EXPECT_FALSE(lm::MissionEnqueue::buildPayload(store, nlohmann::json::object(), payload, err));
}
