/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkPTSFileSystem.h

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
/**
 * @class vtkPTSFileSystem
 * @brief A class manipulate the filesystem of a service.
 *
 * vtkPTSFileSystem can be used to create/delete/list directories on a service.
 */

#ifndef vtkPTSFileSystem_h
#define vtkPTSFileSystem_h

#include "vtkObject.h"
#include "vtkPVFileInformation.h"
#include "vtkRemotingMicroservicesModule.h" // for exports
#include "vtkSmartPointer.h"              // for vtkSmartPointer

#include <memory> // for std::unique_ptr

#include "vtk_rxcpp.h" // for rxcpp
// clang-format off
// ideally, we include rx-lite.hpp here.
#include VTK_REMOTING_RXCPP(rx.hpp)
// clang-format on

class vtkClientSession;
class vtkPVFileInformation;

class VTKREMOTINGMICROSERVICES_EXPORT vtkPTSFileSystem : public vtkObject
{
public:
  static vtkPTSFileSystem* New();
  vtkTypeMacro(vtkPTSFileSystem, vtkObject);
  void PrintSelf(ostream& os, vtkIndent indent) override;

  ///@{
  /**
   * Returns an observable of the status of the operation
   * This is a single value observable.
   *
   * @section Triggers Triggers
   *
   * * on_next: once the operation completes
   *
   * * on_error: if session is not set, std::runtime_error is thrown
   *
   * * on_completed: right after on_next since this is a single value observable
   */

  rxcpp::observable<bool> DirectoryExists(const std::string& path);
  rxcpp::observable<bool> MakeDirectory(const std::string& absolutePath);
  rxcpp::observable<bool> DeleteDirectory(const std::string& absolutePath);
  rxcpp::observable<bool> RenameDirectory(
    const std::string& oldAbsolutePath, const std::string& newAbsolutePath);
  ///@}

  /**
   * Returns an observable of a vtkPVFileInformation object holding the contents
   * of the directory.
   * This is a single value observable.
   *
   * @section Triggers Triggers
   *
   * * on_next: once the operation completes
   *
   * * on_error: if session is not set, std::runtime_error is thrown
   *
   * * on_completed: right after on_next since this is a single value observable
   */
  rxcpp::observable<vtkSmartPointer<vtkPVFileInformation>> ListDirectory(
    const std::string& absolutePath);

  ///@{
  /**
   */
  void SetSession(vtkClientSession* session);
  vtkClientSession* GetSession() const;
  ///@}

  ///@{
  /** Get/Set associated service location.
   * Accepted values are vtkClientSession::ServiceTypes
   */
  void SetLocation(vtkTypeUInt32 location);
  vtkTypeUInt32 GetLocation() const;
  ///@}

protected:
  vtkPTSFileSystem();
  ~vtkPTSFileSystem() override;

private:
  vtkPTSFileSystem(const vtkPTSFileSystem&) = delete;
  void operator=(const vtkPTSFileSystem&) = delete;

  class vtkInternals;
  std::unique_ptr<vtkInternals> Internals;
};

#endif
