//===-- runtime/io-error.cpp ------------------------------------*- 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
//
//===----------------------------------------------------------------------===//

#include "io-error.h"
#include "config.h"
#include "magic-numbers.h"
#include "tools.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 | 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);
        }
      }
    } else if (msg) {
      va_list ap;
      va_start(ap, msg);
      CrashArgs(msg, 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::SignalErrno() { SignalError(errno); }

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

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

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

  char *newBuf;
  // Following code is taken from llvm/lib/Support/Errno.cpp
  // in LLVM v9.0.1
#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.
  newBuf = ::strerror_r(ioStat_, buffer, bufferLength);
#else
  return ::strerror_r(ioStat_, buffer, bufferLength) == 0;
#endif
#elif HAVE_DECL_STRERROR_S // "Windows Secure API"
  return ::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.
  newBuf = strerror(ioStat_);
#else
  // Strange that this system doesn't even have strerror
  return false;
#endif
  ::strncpy(buffer, newBuf, bufferLength - 1);
  buffer[bufferLength - 1] = '\n';
  return true;
}
} // namespace Fortran::runtime::io
