//===-- flang/unittests/RuntimeGTest/Format.cpp -----------------*- C++ -*-===//
//
// 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 "CrashHandlerFixture.h"
#include "../runtime/format-implementation.h"
#include "../runtime/io-error.h"
#include <string>
#include <tuple>
#include <vector>

using namespace Fortran::runtime;
using namespace Fortran::runtime::io;
using namespace std::literals::string_literals;

using ResultsTy = std::vector<std::string>;

// A test harness context for testing FormatControl
class TestFormatContext : public IoErrorHandler {
public:
  using CharType = char;
  TestFormatContext() : IoErrorHandler{"format.cpp", 1} {}
  bool Emit(const char *, std::size_t);
  bool Emit(const char16_t *, std::size_t);
  bool Emit(const char32_t *, std::size_t);
  bool AdvanceRecord(int = 1);
  void HandleRelativePosition(std::int64_t);
  void HandleAbsolutePosition(std::int64_t);
  void Report(const DataEdit &);
  ResultsTy results;
  MutableModes &mutableModes() { return mutableModes_; }

private:
  MutableModes mutableModes_;
};

bool TestFormatContext::Emit(const char *s, std::size_t len) {
  std::string str{s, len};
  results.push_back("'"s + str + '\'');
  return true;
}
bool TestFormatContext::Emit(const char16_t *, std::size_t) {
  Crash("TestFormatContext::Emit(const char16_t *) called");
  return false;
}
bool TestFormatContext::Emit(const char32_t *, std::size_t) {
  Crash("TestFormatContext::Emit(const char32_t *) called");
  return false;
}

bool TestFormatContext::AdvanceRecord(int n) {
  while (n-- > 0) {
    results.emplace_back("/");
  }
  return true;
}

void TestFormatContext::HandleAbsolutePosition(std::int64_t n) {
  results.push_back("T"s + std::to_string(n));
}

void TestFormatContext::HandleRelativePosition(std::int64_t n) {
  if (n < 0) {
    results.push_back("TL"s + std::to_string(-n));
  } else {
    results.push_back(std::to_string(n) + 'X');
  }
}

void TestFormatContext::Report(const DataEdit &edit) {
  std::string str{edit.descriptor};
  if (edit.repeat != 1) {
    str = std::to_string(edit.repeat) + '*' + str;
  }
  if (edit.variation) {
    str += edit.variation;
  }
  if (edit.width) {
    str += std::to_string(*edit.width);
  }
  if (edit.digits) {
    str += "."s + std::to_string(*edit.digits);
  }
  if (edit.expoDigits) {
    str += "E"s + std::to_string(*edit.expoDigits);
  }
  // modes?
  results.push_back(str);
}

struct FormatTests : public CrashHandlerFixture {};

TEST(FormatTests, FormatStringTraversal) {

  using ParamsTy = std::tuple<int, const char *, ResultsTy, int>;

  static const std::vector<ParamsTy> params{
      {1, "('PI=',F9.7)", ResultsTy{"'PI='", "F9.7"}, 1},
      {1, "(3HPI=F9.7)", ResultsTy{"'PI='", "F9.7"}, 1},
      {1, "(3HPI=/F9.7)", ResultsTy{"'PI='", "/", "F9.7"}, 1},
      {2, "('PI=',F9.7)", ResultsTy{"'PI='", "F9.7", "/", "'PI='", "F9.7"}, 1},
      {2, "(2('PI=',F9.7),'done')",
          ResultsTy{"'PI='", "F9.7", "'PI='", "F9.7", "'done'"}, 1},
      {2, "(3('PI=',F9.7,:),'tooFar')",
          ResultsTy{"'PI='", "F9.7", "'PI='", "F9.7"}, 1},
      {2, "(*('PI=',F9.7,:),'tooFar')",
          ResultsTy{"'PI='", "F9.7", "'PI='", "F9.7"}, 1},
      {1, "(3F9.7)", ResultsTy{"2*F9.7"}, 2},
  };

  for (const auto &[n, format, expect, repeat] : params) {
    TestFormatContext context;
    FormatControl<decltype(context)> control{
        context, format, std::strlen(format)};

    for (auto i{0}; i < n; i++) {
      context.Report(/*edit=*/control.GetNextDataEdit(context, repeat));
    }
    control.Finish(context);

    auto iostat{context.GetIoStat()};
    ASSERT_EQ(iostat, 0) << "Expected iostat == 0, but GetIoStat() == "
                         << iostat;

    // Create strings of the expected/actual results for printing errors
    std::string allExpectedResults{""}, allActualResults{""};
    for (const auto &res : context.results) {
      allActualResults += " "s + res;
    }
    for (const auto &res : expect) {
      allExpectedResults += " "s + res;
    }

    const auto &results = context.results;
    ASSERT_EQ(expect, results) << "Expected '" << allExpectedResults
                               << "' but got '" << allActualResults << "'";
  }
}

struct InvalidFormatFailure : CrashHandlerFixture {};

TEST(InvalidFormatFailure, ParenMismatch) {
  static constexpr const char *format{"("};
  static constexpr int repeat{1};

  TestFormatContext context;
  FormatControl<decltype(context)> control{
      context, format, std::strlen(format)};

  ASSERT_DEATH(
      context.Report(/*edit=*/control.GetNextDataEdit(context, repeat)),
      R"(FORMAT missing at least one '\)')");
}

TEST(InvalidFormatFailure, MissingPrecision) {
  static constexpr const char *format{"(F9.)"};
  static constexpr int repeat{1};

  TestFormatContext context;
  FormatControl<decltype(context)> control{
      context, format, std::strlen(format)};

  ASSERT_DEATH(
      context.Report(/*edit=*/control.GetNextDataEdit(context, repeat)),
      R"(Invalid FORMAT: integer expected at '\)')");
}

TEST(InvalidFormatFailure, MissingFormatWidth) {
  static constexpr const char *format{"(F.9)"};
  static constexpr int repeat{1};

  TestFormatContext context;
  FormatControl<decltype(context)> control{
      context, format, std::strlen(format)};

  ASSERT_DEATH(
      context.Report(/*edit=*/control.GetNextDataEdit(context, repeat)),
      "Invalid FORMAT: integer expected at '.'");
}
