//===-- 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();
  void 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; }
  void BeginReadingRecord() {}
  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);
  void 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_
