// SPDX-FileCopyrightText: Copyright (c) Kitware Inc.
// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
// SPDX-License-Identifier: BSD-3-Clause
/**
 * @class   vtkGenericIOUtilities
 *
 *
 * This file provides some common utility functions that are used in the
 * implementation of GenericIO readers.
 */

#ifndef vtkGenericIOUtilities_h
#define vtkGenericIOUtilities_h

#include "vtkType.h" // for vtkIdType

#include <algorithm>  // for std::find_if
#include <functional> // for std::ptr_fun
#include <string>     // for std::string

#include "vtk_mpi.h" // MPI

class vtkMultiProcessController;
class vtkDataArray;

namespace gio
{
class GenericIOReader;
class GenericIOWriter;
}

namespace vtkGenericIOUtilities
{

//==============================================================================
//@{
/**
 * Trims leading whitespace from a string.
 */
inline std::string& ltrim(std::string& s)
{
  s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](int ch) { return !std::isspace(ch); }));
  return s;
}
//@}

//==============================================================================
//@{
/**
 * Trims trailing whitespace from a string.
 */
inline std::string& rtrim(std::string& s)
{
  s.erase(
    std::find_if(s.rbegin(), s.rend(), [](int ch) { return !std::isspace(ch); }).base(), s.end());
  return s;
}
//@}

//==============================================================================
/**
 * Trims leading & trailing whitespace from a string.
 */
inline std::string& trim(std::string& s)
{
  return ltrim(rtrim(s));
}

//==============================================================================
/**
 * Returns the corresponding MPI communicator for the multi-process
 * controller used by this instance.
 */
MPI_Comm GetMPICommunicator(vtkMultiProcessController* mpc);

//==============================================================================
/**
 * This method parses the data in the rawbuffer and reads it into a vtkDataArray
 * that can be attached as vtkPointData to a vtkDataSet, in this case, a
 * vtkUnstructuredGrid that consists of the particles.
 */
vtkDataArray* GetVtkDataArray(std::string name, int type, void* rawBuffer, int N);

//==============================================================================
/**
 * This method accesses the user-supplied buffer at the given index and
 * returns the data as a vtkIdType. It is intended as a convenience method
 * to allow the user to access the data in an agnostic-type fashion.
 */
vtkIdType GetIdFromRawBuffer(const int type, void* buffer, vtkIdType buffer_idx);

//==============================================================================
/**
 * This method accesses the user-supplied buffer at the given index and
 * returns the data as a double. It is intended as a convenience method
 * to allow the user to access the data in an agnostic-type fashion.
 */
double GetDoubleFromRawBuffer(const int type, void* buffer, vtkIdType buffer_idx);

//==============================================================================
/**
 * This method constructs and returns the underlying GenericIO reader.
 */
gio::GenericIOReader* GetReader(
  MPI_Comm comm, bool posix, int distribution, const std::string& fileName);

//==============================================================================
/**
 * This method constructs and returns the underlying GenericIO writer.
 * The returned writer will have its filename set already
 */
gio::GenericIOWriter* GetWriter(MPI_Comm comm, const std::string& fileName);

//==============================================================================
//@{
/**
 * If the pointer given is non-nullptr this function deletes the string and
 * set the pointer to nullptr.  This sets the pointer variable in the calling
 * function since the pointer is passed by reference.
 */
inline void SafeDeleteString(char*& str)
{
  if (str != nullptr)
  {
    delete[] str;
    str = nullptr;
  }
}
//@}
}

#endif /* vtkGenericIOUtilities_h */
// VTK-HeaderTest-Exclude: vtkGenericIOUtilities.h
