//===-- runtime/io-stmt.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
//
//===----------------------------------------------------------------------===//

// Representations of the state of an I/O statement in progress

#ifndef FORTRAN_RUNTIME_IO_STMT_H_
#define FORTRAN_RUNTIME_IO_STMT_H_

#include "connection.h"
#include "descriptor.h"
#include "file.h"
#include "format.h"
#include "internal-unit.h"
#include "io-api.h"
#include "io-error.h"
#include <functional>
#include <type_traits>
#include <variant>

namespace Fortran::runtime::io {

class ExternalFileUnit;

class OpenStatementState;
class InquireUnitState;
class InquireNoUnitState;
class InquireUnconnectedFileState;
class InquireIOLengthState;
class ExternalMiscIoStatementState;
class CloseStatementState;
class NoopCloseStatementState;

template <Direction, typename CHAR = char>
class InternalFormattedIoStatementState;
template <Direction, typename CHAR = char> class InternalListIoStatementState;
template <Direction, typename CHAR = char>
class ExternalFormattedIoStatementState;
template <Direction> class ExternalListIoStatementState;
template <Direction> class UnformattedIoStatementState;

struct InputStatementState {};
struct OutputStatementState {};
template <Direction D>
using IoDirectionState = std::conditional_t<D == Direction::Input,
    InputStatementState, OutputStatementState>;
struct FormattedIoStatementState {};

// The Cookie type in the I/O API is a pointer (for C) to this class.
class IoStatementState {
public:
  template <typename A> explicit IoStatementState(A &x) : u_{x} {}

  // These member functions each project themselves into the active alternative.
  // They're used by per-data-item routines in the I/O API (e.g., OutputReal64)
  // to interact with the state of the I/O statement in progress.
  // This design avoids virtual member functions and function pointers,
  // which may not have good support in some runtime environments.
  std::optional<DataEdit> GetNextDataEdit(int = 1);
  bool Emit(const char *, std::size_t, std::size_t elementBytes = 0);
  std::optional<char32_t> GetCurrentChar(); // vacant after end of record
  bool AdvanceRecord(int = 1);
  void BackspaceRecord();
  void HandleRelativePosition(std::int64_t);
  int EndIoStatement();
  ConnectionState &GetConnectionState();
  IoErrorHandler &GetIoErrorHandler() const;
  ExternalFileUnit *GetExternalFileUnit() const; // null if internal unit
  MutableModes &mutableModes();
  bool BeginReadingRecord();
  void FinishReadingRecord();
  bool Inquire(InquiryKeywordHash, char *, std::size_t);
  bool Inquire(InquiryKeywordHash, bool &);
  bool Inquire(InquiryKeywordHash, std::int64_t, bool &); // PENDING=
  bool Inquire(InquiryKeywordHash, std::int64_t &);

  // N.B.: this also works with base classes
  template <typename A> A *get_if() const {
    return std::visit(
        [](auto &x) -> A * {
          if constexpr (std::is_convertible_v<decltype(x.get()), A &>) {
            return &x.get();
          }
          return nullptr;
        },
        u_);
  }

  bool EmitRepeated(char, std::size_t);
  bool EmitField(const char *, std::size_t length, std::size_t width);

  std::optional<char32_t> SkipSpaces(std::optional<int> &remaining);
  std::optional<char32_t> NextInField(std::optional<int> &remaining);
  std::optional<char32_t> GetNextNonBlank(); // can advance record

  template <Direction D> void CheckFormattedStmtType(const char *name) {
    if (!get_if<FormattedIoStatementState>() ||
        !get_if<IoDirectionState<D>>()) {
      GetIoErrorHandler().Crash(
          "%s called for I/O statement that is not formatted %s", name,
          D == Direction::Output ? "output" : "input");
    }
  }

private:
  std::variant<std::reference_wrapper<OpenStatementState>,
      std::reference_wrapper<CloseStatementState>,
      std::reference_wrapper<NoopCloseStatementState>,
      std::reference_wrapper<
          InternalFormattedIoStatementState<Direction::Output>>,
      std::reference_wrapper<
          InternalFormattedIoStatementState<Direction::Input>>,
      std::reference_wrapper<InternalListIoStatementState<Direction::Output>>,
      std::reference_wrapper<InternalListIoStatementState<Direction::Input>>,
      std::reference_wrapper<
          ExternalFormattedIoStatementState<Direction::Output>>,
      std::reference_wrapper<
          ExternalFormattedIoStatementState<Direction::Input>>,
      std::reference_wrapper<ExternalListIoStatementState<Direction::Output>>,
      std::reference_wrapper<ExternalListIoStatementState<Direction::Input>>,
      std::reference_wrapper<UnformattedIoStatementState<Direction::Output>>,
      std::reference_wrapper<UnformattedIoStatementState<Direction::Input>>,
      std::reference_wrapper<InquireUnitState>,
      std::reference_wrapper<InquireNoUnitState>,
      std::reference_wrapper<InquireUnconnectedFileState>,
      std::reference_wrapper<InquireIOLengthState>,
      std::reference_wrapper<ExternalMiscIoStatementState>>
      u_;
};

// Base class for all per-I/O statement state classes.
// Inherits IoErrorHandler from its base.
struct IoStatementBase : public DefaultFormatControlCallbacks {
  using DefaultFormatControlCallbacks::DefaultFormatControlCallbacks;
  int EndIoStatement();
  std::optional<DataEdit> GetNextDataEdit(IoStatementState &, int = 1);
  ExternalFileUnit *GetExternalFileUnit() const { return nullptr; }
  bool BeginReadingRecord() { return true; }
  void FinishReadingRecord() {}
  bool Inquire(InquiryKeywordHash, char *, std::size_t);
  bool Inquire(InquiryKeywordHash, bool &);
  bool Inquire(InquiryKeywordHash, std::int64_t, bool &);
  bool Inquire(InquiryKeywordHash, std::int64_t &);
  void BadInquiryKeywordHashCrash(InquiryKeywordHash);
};

// Common state for list-directed internal & external I/O
template <Direction> class ListDirectedStatementState;
template <>
class ListDirectedStatementState<Direction::Output>
    : public FormattedIoStatementState {
public:
  static std::size_t RemainingSpaceInRecord(const ConnectionState &);
  bool NeedAdvance(const ConnectionState &, std::size_t) const;
  bool EmitLeadingSpaceOrAdvance(
      IoStatementState &, std::size_t, bool isCharacter = false);
  std::optional<DataEdit> GetNextDataEdit(
      IoStatementState &, int maxRepeat = 1);
  bool lastWasUndelimitedCharacter{false};
};
template <>
class ListDirectedStatementState<Direction::Input>
    : public FormattedIoStatementState {
public:
  // Skips value separators, handles repetition and null values.
  // Vacant when '/' appears; present with descriptor == ListDirectedNullValue
  // when a null value appears.
  std::optional<DataEdit> GetNextDataEdit(
      IoStatementState &, int maxRepeat = 1);

private:
  int remaining_{0}; // for "r*" repetition
  std::int64_t initialRecordNumber_;
  std::int64_t initialPositionInRecord_;
  bool isFirstItem_{true}; // leading separator implies null first item
  bool hitSlash_{false}; // once '/' is seen, nullify further items
  bool realPart_{false};
  bool imaginaryPart_{false};
};

template <Direction DIR, typename CHAR = char>
class InternalIoStatementState : public IoStatementBase,
                                 public IoDirectionState<DIR> {
public:
  using CharType = CHAR;
  using Buffer =
      std::conditional_t<DIR == Direction::Input, const CharType *, CharType *>;
  InternalIoStatementState(Buffer, std::size_t,
      const char *sourceFile = nullptr, int sourceLine = 0);
  InternalIoStatementState(
      const Descriptor &, const char *sourceFile = nullptr, int sourceLine = 0);
  int EndIoStatement();
  bool Emit(const CharType *, std::size_t chars /* not necessarily bytes */,
      std::size_t elementBytes = 0);
  std::optional<char32_t> GetCurrentChar();
  bool AdvanceRecord(int = 1);
  void BackspaceRecord();
  ConnectionState &GetConnectionState() { return unit_; }
  MutableModes &mutableModes() { return unit_.modes; }
  void HandleRelativePosition(std::int64_t);
  void HandleAbsolutePosition(std::int64_t);

protected:
  bool free_{true};
  InternalDescriptorUnit<DIR> unit_;
};

template <Direction DIR, typename CHAR>
class InternalFormattedIoStatementState
    : public InternalIoStatementState<DIR, CHAR>,
      public FormattedIoStatementState {
public:
  using CharType = CHAR;
  using typename InternalIoStatementState<DIR, CharType>::Buffer;
  InternalFormattedIoStatementState(Buffer internal, std::size_t internalLength,
      const CharType *format, std::size_t formatLength,
      const char *sourceFile = nullptr, int sourceLine = 0);
  InternalFormattedIoStatementState(const Descriptor &, const CharType *format,
      std::size_t formatLength, const char *sourceFile = nullptr,
      int sourceLine = 0);
  IoStatementState &ioStatementState() { return ioStatementState_; }
  int EndIoStatement();
  std::optional<DataEdit> GetNextDataEdit(
      IoStatementState &, int maxRepeat = 1) {
    return format_.GetNextDataEdit(*this, maxRepeat);
  }

private:
  IoStatementState ioStatementState_; // points to *this
  using InternalIoStatementState<DIR, CharType>::unit_;
  // format_ *must* be last; it may be partial someday
  FormatControl<InternalFormattedIoStatementState> format_;
};

template <Direction DIR, typename CHAR>
class InternalListIoStatementState : public InternalIoStatementState<DIR, CHAR>,
                                     public ListDirectedStatementState<DIR> {
public:
  using CharType = CHAR;
  using typename InternalIoStatementState<DIR, CharType>::Buffer;
  InternalListIoStatementState(Buffer internal, std::size_t internalLength,
      const char *sourceFile = nullptr, int sourceLine = 0);
  InternalListIoStatementState(
      const Descriptor &, const char *sourceFile = nullptr, int sourceLine = 0);
  IoStatementState &ioStatementState() { return ioStatementState_; }
  using ListDirectedStatementState<DIR>::GetNextDataEdit;

private:
  IoStatementState ioStatementState_; // points to *this
  using InternalIoStatementState<DIR, CharType>::unit_;
};

class ExternalIoStatementBase : public IoStatementBase {
public:
  ExternalIoStatementBase(
      ExternalFileUnit &, const char *sourceFile = nullptr, int sourceLine = 0);
  ExternalFileUnit &unit() { return unit_; }
  MutableModes &mutableModes();
  ConnectionState &GetConnectionState();
  int EndIoStatement();
  ExternalFileUnit *GetExternalFileUnit() { return &unit_; }

private:
  ExternalFileUnit &unit_;
};

template <Direction DIR>
class ExternalIoStatementState : public ExternalIoStatementBase,
                                 public IoDirectionState<DIR> {
public:
  using ExternalIoStatementBase::ExternalIoStatementBase;
  int EndIoStatement();
  bool Emit(const char *, std::size_t, std::size_t elementBytes = 0);
  bool Emit(const char16_t *, std::size_t chars /* not bytes */);
  bool Emit(const char32_t *, std::size_t chars /* not bytes */);
  std::optional<char32_t> GetCurrentChar();
  bool AdvanceRecord(int = 1);
  void BackspaceRecord();
  void HandleRelativePosition(std::int64_t);
  void HandleAbsolutePosition(std::int64_t);
  bool BeginReadingRecord();
  void FinishReadingRecord();
};

template <Direction DIR, typename CHAR>
class ExternalFormattedIoStatementState : public ExternalIoStatementState<DIR>,
                                          public FormattedIoStatementState {
public:
  using CharType = CHAR;
  ExternalFormattedIoStatementState(ExternalFileUnit &, const CharType *format,
      std::size_t formatLength, const char *sourceFile = nullptr,
      int sourceLine = 0);
  MutableModes &mutableModes() { return mutableModes_; }
  int EndIoStatement();
  std::optional<DataEdit> GetNextDataEdit(
      IoStatementState &, int maxRepeat = 1) {
    return format_.GetNextDataEdit(*this, maxRepeat);
  }

private:
  // These are forked from ConnectionState's modes at the beginning
  // of each formatted I/O statement so they may be overridden by control
  // edit descriptors during the statement.
  MutableModes mutableModes_;
  FormatControl<ExternalFormattedIoStatementState> format_;
};

template <Direction DIR>
class ExternalListIoStatementState : public ExternalIoStatementState<DIR>,
                                     public ListDirectedStatementState<DIR> {
public:
  using ExternalIoStatementState<DIR>::ExternalIoStatementState;
  using ListDirectedStatementState<DIR>::GetNextDataEdit;
};

template <Direction DIR>
class UnformattedIoStatementState : public ExternalIoStatementState<DIR> {
public:
  using ExternalIoStatementState<DIR>::ExternalIoStatementState;
  bool Receive(char *, std::size_t, std::size_t elementBytes = 0);
  bool Emit(const char *, std::size_t, std::size_t elementBytes = 0);
};

class OpenStatementState : public ExternalIoStatementBase {
public:
  OpenStatementState(ExternalFileUnit &unit, bool wasExtant,
      const char *sourceFile = nullptr, int sourceLine = 0)
      : ExternalIoStatementBase{unit, sourceFile, sourceLine}, wasExtant_{
                                                                   wasExtant} {}
  bool wasExtant() const { return wasExtant_; }
  void set_status(OpenStatus status) { status_ = status; } // STATUS=
  void set_path(const char *, std::size_t); // FILE=
  void set_position(Position position) { position_ = position; } // POSITION=
  void set_action(Action action) { action_ = action; } // ACTION=
  void set_convert(Convert convert) { convert_ = convert; } // CONVERT=
  void set_access(Access access) { access_ = access; } // ACCESS=
  void set_isUnformatted(bool yes = true) { isUnformatted_ = yes; } // FORM=
  int EndIoStatement();

private:
  bool wasExtant_;
  std::optional<OpenStatus> status_;
  Position position_{Position::AsIs};
  std::optional<Action> action_;
  Convert convert_{Convert::Native};
  OwningPtr<char> path_;
  std::size_t pathLength_;
  std::optional<bool> isUnformatted_;
  std::optional<Access> access_;
};

class CloseStatementState : public ExternalIoStatementBase {
public:
  CloseStatementState(ExternalFileUnit &unit, const char *sourceFile = nullptr,
      int sourceLine = 0)
      : ExternalIoStatementBase{unit, sourceFile, sourceLine} {}
  void set_status(CloseStatus status) { status_ = status; }
  int EndIoStatement();

private:
  CloseStatus status_{CloseStatus::Keep};
};

// For CLOSE(bad unit) and INQUIRE(unconnected unit)
class NoUnitIoStatementState : public IoStatementBase {
public:
  IoStatementState &ioStatementState() { return ioStatementState_; }
  MutableModes &mutableModes() { return connection_.modes; }
  ConnectionState &GetConnectionState() { return connection_; }
  int EndIoStatement();

protected:
  template <typename A>
  NoUnitIoStatementState(const char *sourceFile, int sourceLine, A &stmt)
      : IoStatementBase{sourceFile, sourceLine}, ioStatementState_{stmt} {}

private:
  IoStatementState ioStatementState_; // points to *this
  ConnectionState connection_;
};

class NoopCloseStatementState : public NoUnitIoStatementState {
public:
  NoopCloseStatementState(const char *sourceFile, int sourceLine)
      : NoUnitIoStatementState{sourceFile, sourceLine, *this} {}
  void set_status(CloseStatus) {} // discards
};

extern template class InternalIoStatementState<Direction::Output>;
extern template class InternalIoStatementState<Direction::Input>;
extern template class InternalFormattedIoStatementState<Direction::Output>;
extern template class InternalFormattedIoStatementState<Direction::Input>;
extern template class InternalListIoStatementState<Direction::Output>;
extern template class InternalListIoStatementState<Direction::Input>;
extern template class ExternalIoStatementState<Direction::Output>;
extern template class ExternalIoStatementState<Direction::Input>;
extern template class ExternalFormattedIoStatementState<Direction::Output>;
extern template class ExternalFormattedIoStatementState<Direction::Input>;
extern template class ExternalListIoStatementState<Direction::Output>;
extern template class ExternalListIoStatementState<Direction::Input>;
extern template class UnformattedIoStatementState<Direction::Output>;
extern template class UnformattedIoStatementState<Direction::Input>;
extern template class FormatControl<
    InternalFormattedIoStatementState<Direction::Output>>;
extern template class FormatControl<
    InternalFormattedIoStatementState<Direction::Input>>;
extern template class FormatControl<
    ExternalFormattedIoStatementState<Direction::Output>>;
extern template class FormatControl<
    ExternalFormattedIoStatementState<Direction::Input>>;

class InquireUnitState : public ExternalIoStatementBase {
public:
  InquireUnitState(ExternalFileUnit &unit, const char *sourceFile = nullptr,
      int sourceLine = 0);
  bool Inquire(InquiryKeywordHash, char *, std::size_t);
  bool Inquire(InquiryKeywordHash, bool &);
  bool Inquire(InquiryKeywordHash, std::int64_t, bool &);
  bool Inquire(InquiryKeywordHash, std::int64_t &);
};

class InquireNoUnitState : public NoUnitIoStatementState {
public:
  InquireNoUnitState(const char *sourceFile = nullptr, int sourceLine = 0);
  bool Inquire(InquiryKeywordHash, char *, std::size_t);
  bool Inquire(InquiryKeywordHash, bool &);
  bool Inquire(InquiryKeywordHash, std::int64_t, bool &);
  bool Inquire(InquiryKeywordHash, std::int64_t &);
};

class InquireUnconnectedFileState : public NoUnitIoStatementState {
public:
  InquireUnconnectedFileState(OwningPtr<char> &&path,
      const char *sourceFile = nullptr, int sourceLine = 0);
  bool Inquire(InquiryKeywordHash, char *, std::size_t);
  bool Inquire(InquiryKeywordHash, bool &);
  bool Inquire(InquiryKeywordHash, std::int64_t, bool &);
  bool Inquire(InquiryKeywordHash, std::int64_t &);

private:
  OwningPtr<char> path_; // trimmed and NUL terminated
};

class InquireIOLengthState : public NoUnitIoStatementState,
                             public OutputStatementState {
public:
  InquireIOLengthState(const char *sourceFile = nullptr, int sourceLine = 0);
  std::size_t bytes() const { return bytes_; }
  bool Emit(const char *, std::size_t, std::size_t elementBytes = 0);

private:
  std::size_t bytes_{0};
};

class ExternalMiscIoStatementState : public ExternalIoStatementBase {
public:
  enum Which { Flush, Backspace, Endfile, Rewind };
  ExternalMiscIoStatementState(ExternalFileUnit &unit, Which which,
      const char *sourceFile = nullptr, int sourceLine = 0)
      : ExternalIoStatementBase{unit, sourceFile, sourceLine}, which_{which} {}
  int EndIoStatement();

private:
  Which which_;
};

} // namespace Fortran::runtime::io
#endif // FORTRAN_RUNTIME_IO_STMT_H_
