/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing#kwsys for details.  */
#ifndef @KWSYS_NAMESPACE@_FStream_hxx
#define @KWSYS_NAMESPACE@_FStream_hxx

#include <@KWSYS_NAMESPACE@/Configure.hxx>

#include <@KWSYS_NAMESPACE@/Encoding.hxx>

#include <fstream>
#if defined(_WIN32)
#if !defined(_MSC_VER) && @KWSYS_NAMESPACE@_CXX_HAS_EXT_STDIO_FILEBUF_H
#include <ext/stdio_filebuf.h>
#endif
#endif

namespace @KWSYS_NAMESPACE@ {
#if defined(_WIN32) &&                                                        \
  (defined(_MSC_VER) || @KWSYS_NAMESPACE@_CXX_HAS_EXT_STDIO_FILEBUF_H)
#if defined(_NOEXCEPT)
#define @KWSYS_NAMESPACE@_FStream_NOEXCEPT _NOEXCEPT
#else
#define @KWSYS_NAMESPACE@_FStream_NOEXCEPT
#endif

#if defined(_MSC_VER)

template <typename CharType, typename Traits>
class basic_filebuf : public std::basic_filebuf<CharType, Traits>
{
#if _MSC_VER >= 1400
public:
  typedef std::basic_filebuf<CharType, Traits> my_base_type;
  basic_filebuf* open(char const* s, std::ios_base::openmode mode)
  {
    const std::wstring wstr = Encoding::ToWindowsExtendedPath(s);
    return static_cast<basic_filebuf*>(my_base_type::open(wstr.c_str(), mode));
  }
#endif
};

#else

inline std::wstring getcmode(const std::ios_base::openmode mode)
{
  std::wstring cmode;
  bool plus = false;
  if (mode & std::ios_base::app) {
    cmode += L"a";
    plus = mode & std::ios_base::in ? true : false;
  } else if (mode & std::ios_base::trunc ||
             (mode & std::ios_base::out && (mode & std::ios_base::in) == 0)) {
    cmode += L"w";
    plus = mode & std::ios_base::in ? true : false;
  } else {
    cmode += L"r";
    plus = mode & std::ios_base::out ? true : false;
  }
  if (plus) {
    cmode += L"+";
  }
  if (mode & std::ios_base::binary) {
    cmode += L"b";
  } else {
    cmode += L"t";
  }
  return cmode;
};

#endif

template <typename CharType, typename Traits = std::char_traits<CharType> >
class basic_efilebuf
{
public:
#if defined(_MSC_VER)
  typedef basic_filebuf<CharType, Traits> internal_buffer_type;
#else
  typedef __gnu_cxx::stdio_filebuf<CharType, Traits> internal_buffer_type;
#endif

  basic_efilebuf()
    : file_(0)
  {
    buf_ = 0;
  }

  bool _open(char const* file_name, std::ios_base::openmode mode)
  {
    if (is_open() || file_) {
      return false;
    }
#if defined(_MSC_VER)
    const bool success = buf_->open(file_name, mode) != 0;
#else
    const std::wstring wstr = Encoding::ToWindowsExtendedPath(file_name);
    bool success = false;
    std::wstring cmode = getcmode(mode);
    file_ = _wfopen(wstr.c_str(), cmode.c_str());
    if (file_) {
      if (buf_) {
        delete buf_;
      }
      buf_ = new internal_buffer_type(file_, mode);
      success = true;
    }
#endif
    return success;
  }

  bool is_open()
  {
    if (!buf_) {
      return false;
    }
    return buf_->is_open();
  }

  bool is_open() const
  {
    if (!buf_) {
      return false;
    }
    return buf_->is_open();
  }

  bool _close()
  {
    bool success = false;
    if (buf_) {
      success = buf_->close() != 0;
#if !defined(_MSC_VER)
      if (file_) {
        success = fclose(file_) == 0 ? success : false;
        file_ = 0;
      }
#endif
    }
    return success;
  }

  static void _set_state(bool success, std::basic_ios<CharType, Traits>* ios,
                         basic_efilebuf* efilebuf)
  {
#if !defined(_MSC_VER)
    ios->rdbuf(efilebuf->buf_);
#else
    static_cast<void>(efilebuf);
#endif
    if (!success) {
      ios->setstate(std::ios_base::failbit);
    } else {
      ios->clear();
    }
  }

  ~basic_efilebuf()
  {
    if (buf_) {
      delete buf_;
    }
  }

protected:
  internal_buffer_type* buf_;
  FILE* file_;
};

template <typename CharType, typename Traits = std::char_traits<CharType> >
class basic_ifstream : public std::basic_istream<CharType, Traits>,
                       public basic_efilebuf<CharType, Traits>
{
public:
  typedef typename basic_efilebuf<CharType, Traits>::internal_buffer_type
    internal_buffer_type;
  typedef std::basic_istream<CharType, Traits> internal_stream_type;

  basic_ifstream()
    : internal_stream_type(new internal_buffer_type())
  {
    this->buf_ =
      static_cast<internal_buffer_type*>(internal_stream_type::rdbuf());
  }
  explicit basic_ifstream(char const* file_name,
                          std::ios_base::openmode mode = std::ios_base::in)
    : internal_stream_type(new internal_buffer_type())
  {
    this->buf_ =
      static_cast<internal_buffer_type*>(internal_stream_type::rdbuf());
    open(file_name, mode);
  }

  void open(char const* file_name,
            std::ios_base::openmode mode = std::ios_base::in)
  {
    mode = mode | std::ios_base::in;
    this->_set_state(this->_open(file_name, mode), this, this);
  }

  void close() { this->_set_state(this->_close(), this, this); }

  using basic_efilebuf<CharType, Traits>::is_open;

  internal_buffer_type* rdbuf() const { return this->buf_; }

  ~basic_ifstream() @KWSYS_NAMESPACE@_FStream_NOEXCEPT { close(); }
};

template <typename CharType, typename Traits = std::char_traits<CharType> >
class basic_ofstream : public std::basic_ostream<CharType, Traits>,
                       public basic_efilebuf<CharType, Traits>
{
  using basic_efilebuf<CharType, Traits>::is_open;

public:
  typedef typename basic_efilebuf<CharType, Traits>::internal_buffer_type
    internal_buffer_type;
  typedef std::basic_ostream<CharType, Traits> internal_stream_type;

  basic_ofstream()
    : internal_stream_type(new internal_buffer_type())
  {
    this->buf_ =
      static_cast<internal_buffer_type*>(internal_stream_type::rdbuf());
  }
  explicit basic_ofstream(char const* file_name,
                          std::ios_base::openmode mode = std::ios_base::out)
    : internal_stream_type(new internal_buffer_type())
  {
    this->buf_ =
      static_cast<internal_buffer_type*>(internal_stream_type::rdbuf());
    open(file_name, mode);
  }
  void open(char const* file_name,
            std::ios_base::openmode mode = std::ios_base::out)
  {
    mode = mode | std::ios_base::out;
    this->_set_state(this->_open(file_name, mode), this, this);
  }

  void close() { this->_set_state(this->_close(), this, this); }

  internal_buffer_type* rdbuf() const { return this->buf_; }

  ~basic_ofstream() @KWSYS_NAMESPACE@_FStream_NOEXCEPT { close(); }
};

typedef basic_ifstream<char> ifstream;
typedef basic_ofstream<char> ofstream;

#undef @KWSYS_NAMESPACE@_FStream_NOEXCEPT
#else
using std::ofstream;
using std::ifstream;
#endif

namespace FStream {
enum BOM
{
  BOM_None,
  BOM_UTF8,
  BOM_UTF16BE,
  BOM_UTF16LE,
  BOM_UTF32BE,
  BOM_UTF32LE
};

// Read a BOM, if one exists.
// If a BOM exists, the stream is advanced to after the BOM.
// This function requires a seekable stream (but not a relative
// seekable stream).
@KWSYS_NAMESPACE@_EXPORT BOM ReadBOM(std::istream& in);
}
}

#endif
