//===-- runtime/format.h ----------------------------------------*- 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
//
//===----------------------------------------------------------------------===//

// FORMAT string processing

#ifndef FORTRAN_RUNTIME_FORMAT_H_
#define FORTRAN_RUNTIME_FORMAT_H_

#include "environment.h"
#include "io-error.h"
#include "flang/Common/Fortran.h"
#include "flang/Common/optional.h"
#include "flang/Decimal/decimal.h"
#include "flang/Runtime/freestanding-tools.h"
#include <cinttypes>

namespace Fortran::runtime {
class Descriptor;
} // namespace Fortran::runtime

namespace Fortran::runtime::io {

class IoStatementState;

enum EditingFlags {
  blankZero = 1, // BLANK=ZERO or BZ edit
  decimalComma = 2, // DECIMAL=COMMA or DC edit
  signPlus = 4, // SIGN=PLUS or SP edit
};

struct MutableModes {
  std::uint8_t editingFlags{0}; // BN, DP, SS
  enum decimal::FortranRounding round{
      executionEnvironment
          .defaultOutputRoundingMode}; // RP/ROUND='PROCESSOR_DEFAULT'
  bool pad{true}; // PAD= mode on READ
  char delim{'\0'}; // DELIM=
  short scale{0}; // kP
  bool inNamelist{false}; // skip ! comments
  bool nonAdvancing{false}; // ADVANCE='NO', or $ or \ in FORMAT
};

// A single edit descriptor extracted from a FORMAT
struct DataEdit {
  char descriptor; // capitalized: one of A, I, B, O, Z, F, E(N/S/X), D, G

  // Special internal data edit descriptors for list-directed & NAMELIST I/O
  RT_OFFLOAD_VAR_GROUP_BEGIN
  static constexpr char ListDirected{'g'}; // non-COMPLEX list-directed
  static constexpr char ListDirectedRealPart{'r'}; // emit "(r," or "(r;"
  static constexpr char ListDirectedImaginaryPart{'z'}; // emit "z)"
  static constexpr char ListDirectedNullValue{'n'}; // see 13.10.3.2
  static constexpr char DefinedDerivedType{'d'}; // DT defined I/O
  RT_OFFLOAD_VAR_GROUP_END
  constexpr RT_API_ATTRS bool IsListDirected() const {
    return descriptor == ListDirected || descriptor == ListDirectedRealPart ||
        descriptor == ListDirectedImaginaryPart;
  }
  constexpr RT_API_ATTRS bool IsNamelist() const {
    return IsListDirected() && modes.inNamelist;
  }

  char variation{'\0'}; // N, S, or X for EN, ES, EX; G/l for original G/list
  Fortran::common::optional<int> width; // the 'w' field; optional for A
  Fortran::common::optional<int> digits; // the 'm' or 'd' field
  Fortran::common::optional<int> expoDigits; // 'Ee' field
  MutableModes modes;
  int repeat{1};

  // "iotype" &/or "v_list" values for a DT'iotype'(v_list)
  // defined I/O data edit descriptor
  RT_OFFLOAD_VAR_GROUP_BEGIN
  static constexpr std::size_t maxIoTypeChars{32};
  static constexpr std::size_t maxVListEntries{4};
  RT_OFFLOAD_VAR_GROUP_END
  std::uint8_t ioTypeChars{0};
  std::uint8_t vListEntries{0};
  char ioType[maxIoTypeChars];
  int vList[maxVListEntries];
};

// Generates a sequence of DataEdits from a FORMAT statement or
// default-CHARACTER string.  Driven by I/O item list processing.
// Errors are fatal.  See subclause 13.4 in Fortran 2018 for background.
template <typename CONTEXT> class FormatControl {
public:
  using Context = CONTEXT;
  using CharType = char; // formats are always default kind CHARACTER

  RT_API_ATTRS FormatControl() {}
  RT_API_ATTRS FormatControl(const Terminator &, const CharType *format,
      std::size_t formatLength, const Descriptor *formatDescriptor = nullptr,
      int maxHeight = maxMaxHeight);

  // For attempting to allocate in a user-supplied stack area
  static RT_API_ATTRS std::size_t GetNeededSize(int maxHeight) {
    return sizeof(FormatControl) -
        sizeof(Iteration) * (maxMaxHeight - maxHeight);
  }

  // Extracts the next data edit descriptor, handling control edit descriptors
  // along the way.  If maxRepeat==0, this is a peek at the next data edit
  // descriptor.
  RT_API_ATTRS Fortran::common::optional<DataEdit> GetNextDataEdit(
      Context &, int maxRepeat = 1);

  // Emit any remaining character literals after the last data item (on output)
  // and perform remaining record positioning actions.
  RT_API_ATTRS void Finish(Context &);

private:
  RT_OFFLOAD_VAR_GROUP_BEGIN
  static constexpr std::uint8_t maxMaxHeight{100};

  struct Iteration {
    static constexpr int unlimited{-1};
    int start{0}; // offset in format_ of '(' or a repeated edit descriptor
    int remaining{0}; // while >0, decrement and iterate
  };
  RT_OFFLOAD_VAR_GROUP_END

  RT_API_ATTRS void SkipBlanks() {
    while (offset_ < formatLength_ &&
        (format_[offset_] == ' ' || format_[offset_] == '\t' ||
            format_[offset_] == '\v')) {
      ++offset_;
    }
  }
  RT_API_ATTRS CharType PeekNext() {
    SkipBlanks();
    return offset_ < formatLength_ ? format_[offset_] : '\0';
  }
  RT_API_ATTRS CharType GetNextChar(IoErrorHandler &handler) {
    SkipBlanks();
    if (offset_ >= formatLength_) {
      if (formatLength_ == 0) {
        handler.SignalError(
            IostatErrorInFormat, "Empty or badly assigned FORMAT");
      } else {
        handler.SignalError(
            IostatErrorInFormat, "FORMAT missing at least one ')'");
      }
      return '\n';
    }
    return format_[offset_++];
  }
  RT_API_ATTRS int GetIntField(
      IoErrorHandler &, CharType firstCh = '\0', bool *hadError = nullptr);

  // Advances through the FORMAT until the next data edit
  // descriptor has been found; handles control edit descriptors
  // along the way.  Returns the repeat count that appeared
  // before the descriptor (defaulting to 1) and leaves offset_
  // pointing to the data edit.
  RT_API_ATTRS int CueUpNextDataEdit(Context &, bool stop = false);

  static constexpr RT_API_ATTRS CharType Capitalize(CharType ch) {
    return ch >= 'a' && ch <= 'z' ? ch + 'A' - 'a' : ch;
  }

  RT_API_ATTRS void ReportBadFormat(
      Context &context, const char *msg, int offset) const {
    if constexpr (std::is_same_v<CharType, char>) {
      // Echo the bad format in the error message, but trim any leading or
      // trailing spaces.
      int firstNonBlank{0};
      while (firstNonBlank < formatLength_ && format_[firstNonBlank] == ' ') {
        ++firstNonBlank;
      }
      int lastNonBlank{formatLength_ - 1};
      while (lastNonBlank > firstNonBlank && format_[lastNonBlank] == ' ') {
        --lastNonBlank;
      }
      if (firstNonBlank <= lastNonBlank) {
        context.SignalError(IostatErrorInFormat,
            "%s; at offset %d in format '%.*s'", msg, offset,
            lastNonBlank - firstNonBlank + 1, format_ + firstNonBlank);
        return;
      }
    }
    context.SignalError(IostatErrorInFormat, "%s; at offset %d", msg, offset);
  }

  // Data members are arranged and typed so as to reduce size.
  // This structure may be allocated in stack space loaned by the
  // user program for internal I/O.
  const std::uint8_t maxHeight_{maxMaxHeight};
  std::uint8_t height_{0};
  bool freeFormat_{false};
  bool hitEnd_{false};
  const CharType *format_{nullptr};
  int formatLength_{0}; // in units of characters
  int offset_{0}; // next item is at format_[offset_]

  // must be last, may be incomplete
  Iteration stack_[maxMaxHeight];
};
} // namespace Fortran::runtime::io
#endif // FORTRAN_RUNTIME_FORMAT_H_
