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

// Fortran external I/O units

#ifndef FORTRAN_RUNTIME_IO_UNIT_H_
#define FORTRAN_RUNTIME_IO_UNIT_H_

#include "buffer.h"
#include "connection.h"
#include "file.h"
#include "format.h"
#include "io-error.h"
#include "io-stmt.h"
#include "lock.h"
#include "memory.h"
#include "terminator.h"
#include <cstdlib>
#include <cstring>
#include <optional>
#include <variant>

namespace Fortran::runtime::io {

class UnitMap;
class ChildIo;

class ExternalFileUnit : public ConnectionState,
                         public OpenFile,
                         public FileFrame<ExternalFileUnit> {
public:
  explicit ExternalFileUnit(int unitNumber) : unitNumber_{unitNumber} {}
  int unitNumber() const { return unitNumber_; }
  bool swapEndianness() const { return swapEndianness_; }
  bool createdForInternalChildIo() const { return createdForInternalChildIo_; }

  static ExternalFileUnit *LookUp(int unit);
  static ExternalFileUnit &LookUpOrCrash(int unit, const Terminator &);
  static ExternalFileUnit &LookUpOrCreate(
      int unit, const Terminator &, bool &wasExtant);
  static ExternalFileUnit &LookUpOrCreateAnonymous(int unit, Direction,
      std::optional<bool> isUnformatted, const Terminator &);
  static ExternalFileUnit *LookUp(const char *path);
  static ExternalFileUnit &CreateNew(int unit, const Terminator &);
  static ExternalFileUnit *LookUpForClose(int unit);
  static ExternalFileUnit &NewUnit(const Terminator &, bool forChildIo = false);
  static void CloseAll(IoErrorHandler &);
  static void FlushAll(IoErrorHandler &);

  void OpenUnit(std::optional<OpenStatus>, std::optional<Action>, Position,
      OwningPtr<char> &&path, std::size_t pathLength, Convert,
      IoErrorHandler &);
  void OpenAnonymousUnit(std::optional<OpenStatus>, std::optional<Action>,
      Position, Convert, IoErrorHandler &);
  void CloseUnit(CloseStatus, IoErrorHandler &);
  void DestroyClosed();

  bool SetDirection(Direction, IoErrorHandler &);

  template <typename A, typename... X>
  IoStatementState &BeginIoStatement(X &&...xs) {
    lock_.Take(); // dropped in EndIoStatement()
    A &state{u_.emplace<A>(std::forward<X>(xs)...)};
    if constexpr (!std::is_same_v<A, OpenStatementState>) {
      state.mutableModes() = ConnectionState::modes;
    }
    io_.emplace(state);
    return *io_;
  }

  bool Emit(
      const char *, std::size_t, std::size_t elementBytes, IoErrorHandler &);
  bool Receive(char *, std::size_t, std::size_t elementBytes, IoErrorHandler &);
  std::optional<char32_t> GetCurrentChar(IoErrorHandler &);
  void SetLeftTabLimit();
  bool BeginReadingRecord(IoErrorHandler &);
  void FinishReadingRecord(IoErrorHandler &);
  bool AdvanceRecord(IoErrorHandler &);
  void BackspaceRecord(IoErrorHandler &);
  void FlushOutput(IoErrorHandler &);
  void FlushIfTerminal(IoErrorHandler &);
  void Endfile(IoErrorHandler &);
  void Rewind(IoErrorHandler &);
  void EndIoStatement();
  void SetPosition(std::int64_t pos) {
    frameOffsetInFile_ = pos;
    recordOffsetInFrame_ = 0;
    BeginRecord();
  }

  ChildIo *GetChildIo() { return child_.get(); }
  ChildIo &PushChildIo(IoStatementState &);
  void PopChildIo(ChildIo &);

private:
  static UnitMap &GetUnitMap();
  const char *FrameNextInput(IoErrorHandler &, std::size_t);
  void BeginSequentialVariableUnformattedInputRecord(IoErrorHandler &);
  void BeginSequentialVariableFormattedInputRecord(IoErrorHandler &);
  void BackspaceFixedRecord(IoErrorHandler &);
  void BackspaceVariableUnformattedRecord(IoErrorHandler &);
  void BackspaceVariableFormattedRecord(IoErrorHandler &);
  bool SetSequentialVariableFormattedRecordLength();
  void DoImpliedEndfile(IoErrorHandler &);
  void DoEndfile(IoErrorHandler &);
  void CommitWrites();

  int unitNumber_{-1};
  Direction direction_{Direction::Output};
  bool impliedEndfile_{false}; // seq. output has taken place
  bool beganReadingRecord_{false};

  Lock lock_;

  // When an I/O statement is in progress on this unit, holds its state.
  std::variant<std::monostate, OpenStatementState, CloseStatementState,
      ExternalFormattedIoStatementState<Direction::Output>,
      ExternalFormattedIoStatementState<Direction::Input>,
      ExternalListIoStatementState<Direction::Output>,
      ExternalListIoStatementState<Direction::Input>,
      ExternalUnformattedIoStatementState<Direction::Output>,
      ExternalUnformattedIoStatementState<Direction::Input>, InquireUnitState,
      ExternalMiscIoStatementState>
      u_;

  // Points to the active alternative (if any) in u_ for use as a Cookie
  std::optional<IoStatementState> io_;

  // Subtle: The beginning of the frame can't be allowed to advance
  // during a single list-directed READ due to the possibility of a
  // multi-record CHARACTER value with a "r*" repeat count.  So we
  // manage the frame and the current record therein separately.
  std::int64_t frameOffsetInFile_{0};
  std::size_t recordOffsetInFrame_{0}; // of currentRecordNumber

  bool swapEndianness_{false};

  bool createdForInternalChildIo_{false};

  // A stack of child I/O pseudo-units for user-defined derived type
  // I/O that have this unit number.
  OwningPtr<ChildIo> child_;
};

// A pseudo-unit for child I/O statements in user-defined derived type
// I/O subroutines; it forwards operations to the parent I/O statement,
// which can also be a child I/O statement.
class ChildIo {
public:
  ChildIo(IoStatementState &parent, OwningPtr<ChildIo> &&previous)
      : parent_{parent}, previous_{std::move(previous)} {}

  IoStatementState &parent() const { return parent_; }

  void EndIoStatement();

  template <typename A, typename... X>
  IoStatementState &BeginIoStatement(X &&...xs) {
    A &state{u_.emplace<A>(std::forward<X>(xs)...)};
    io_.emplace(state);
    return *io_;
  }

  OwningPtr<ChildIo> AcquirePrevious() { return std::move(previous_); }

  bool CheckFormattingAndDirection(
      Terminator &, const char *what, bool unformatted, Direction);

private:
  IoStatementState &parent_;
  OwningPtr<ChildIo> previous_;
  std::variant<std::monostate,
      ChildFormattedIoStatementState<Direction::Output>,
      ChildFormattedIoStatementState<Direction::Input>,
      ChildListIoStatementState<Direction::Output>,
      ChildListIoStatementState<Direction::Input>,
      ChildUnformattedIoStatementState<Direction::Output>,
      ChildUnformattedIoStatementState<Direction::Input>>
      u_;
  std::optional<IoStatementState> io_;
};

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