//===-- runtime/io-error.cpp ----------------------------------------------===//
//
// 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 "io-error.h"
#include "config.h"
#include "tools.h"
#include "flang/Runtime/magic-numbers.h"
#include <cerrno>
#include <cstdarg>
#include <cstdio>
#include <cstring>

namespace Fortran::runtime::io {

void IoErrorHandler::SignalError(int iostatOrErrno, const char *msg, ...) {
  if (iostatOrErrno == IostatEnd && (flags_ & hasEnd)) {
    if (ioStat_ == IostatOk || ioStat_ < IostatEnd) {
      ioStat_ = IostatEnd;
    }
  } else if (iostatOrErrno == IostatEor && (flags_ & hasEor)) {
    if (ioStat_ == IostatOk || ioStat_ < IostatEor) {
      ioStat_ = IostatEor; // least priority
    }
  } else if (iostatOrErrno != IostatOk) {
    if (flags_ & (hasIoStat | hasIoMsg | hasErr)) {
      if (ioStat_ <= 0) {
        ioStat_ = iostatOrErrno; // priority over END=/EOR=
        if (msg && (flags_ & hasIoMsg)) {
          char buffer[256];
          va_list ap;
          va_start(ap, msg);
          std::vsnprintf(buffer, sizeof buffer, msg, ap);
          ioMsg_ = SaveDefaultCharacter(buffer, std::strlen(buffer) + 1, *this);
          va_end(ap);
        }
      }
    } else if (msg) {
      va_list ap;
      va_start(ap, msg);
      CrashArgs(msg, ap);
      va_end(ap);
    } else if (const char *errstr{IostatErrorString(iostatOrErrno)}) {
      Crash(errstr);
    } else {
      Crash("I/O error (errno=%d): %s", iostatOrErrno,
          std::strerror(iostatOrErrno));
    }
  }
}

void IoErrorHandler::SignalError(int iostatOrErrno) {
  SignalError(iostatOrErrno, nullptr);
}

void IoErrorHandler::Forward(
    int ioStatOrErrno, const char *msg, std::size_t length) {
  if (ioStat_ != IostatOk && msg && (flags_ & hasIoMsg)) {
    ioMsg_ = SaveDefaultCharacter(msg, length, *this);
  }
  if (ioStatOrErrno != IostatOk && msg) {
    SignalError(ioStatOrErrno, "%.*s", static_cast<int>(length), msg);
  } else {
    SignalError(ioStatOrErrno);
  }
}

void IoErrorHandler::SignalErrno() { SignalError(errno); }

void IoErrorHandler::SignalEnd() { SignalError(IostatEnd); }

void IoErrorHandler::SignalEor() { SignalError(IostatEor); }

void IoErrorHandler::SignalPendingError() {
  int error{pendingError_};
  pendingError_ = IostatOk;
  SignalError(error);
}

bool IoErrorHandler::GetIoMsg(char *buffer, std::size_t bufferLength) {
  const char *msg{ioMsg_.get()};
  if (!msg) {
    msg = IostatErrorString(ioStat_ == IostatOk ? pendingError_ : ioStat_);
  }
  if (msg) {
    ToFortranDefaultCharacter(buffer, bufferLength, msg);
    return true;
  }

  // Following code is taken from llvm/lib/Support/Errno.cpp
  // in LLVM v9.0.1 with inadequate modification for Fortran,
  // since rectified.
  bool ok{false};
#if HAVE_STRERROR_R
  // strerror_r is thread-safe.
#if defined(__GLIBC__) && defined(_GNU_SOURCE)
  // glibc defines its own incompatible version of strerror_r
  // which may not use the buffer supplied.
  msg = ::strerror_r(ioStat_, buffer, bufferLength);
#else
  ok = ::strerror_r(ioStat_, buffer, bufferLength) == 0;
#endif
#elif HAVE_DECL_STRERROR_S // "Windows Secure API"
  ok = ::strerror_s(buffer, bufferLength, ioStat_) == 0;
#elif HAVE_STRERROR
  // Copy the thread un-safe result of strerror into
  // the buffer as fast as possible to minimize impact
  // of collision of strerror in multiple threads.
  msg = strerror(ioStat_);
#else
  // Strange that this system doesn't even have strerror
  return false;
#endif
  if (msg) {
    ToFortranDefaultCharacter(buffer, bufferLength, msg);
    return true;
  } else if (ok) {
    std::size_t copied{std::strlen(buffer)};
    if (copied < bufferLength) {
      std::memset(buffer + copied, ' ', bufferLength - copied);
    }
    return true;
  } else {
    return false;
  }
}
} // namespace Fortran::runtime::io
