/*
  This file is part of CDO. CDO is a collection of Operators to
  manipulate and analyse Climate model Data.

  Copyright (C) 2003-2020 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
  See COPYING file for copying and redistribution conditions.

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; version 2 of the License.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
*/

#ifndef CDOSTREAM_H
#define CDOSTREAM_H

#ifdef HAVE_CONFIG_H
#include "config.h" /* _FILE_OFFSET_BITS influence off_t */
#endif

#include <sys/types.h> /* off_t */
#include <vector>
#include <memory>

#include "datarangelist.h"
#include "field.h"

class FileStream;

class CdoStream;

using CdiStreamID = int;
using CdoStreamID = std::shared_ptr<CdoStream>;
#define CDO_STREAM_UNDEF nullptr

class CdoStream
{
public:
  // Constructors
  virtual int openRead() = 0;
  virtual int openWrite(int p_filetype) = 0;
  virtual int openAppend() = 0;

  virtual int inqVlist() = 0;
  virtual void defVlist(int p_vlistID) = 0;

  virtual void inqRecord(int *varID, int *levelID) = 0;
  virtual void defRecord(int varID, int levelID) = 0;

  virtual void readRecord(float *p_data, size_t *nmiss) = 0;
  virtual void readRecord(double *p_data, size_t *nmiss) = 0;
  virtual void readRecord(Field *p_field, size_t *nmiss) = 0;

  virtual void writeRecord(float *p_data, size_t nmiss) = 0;
  virtual void writeRecord(double *p_data, size_t nmiss) = 0;
  virtual void writeRecord(Field *p_field, size_t nmiss) = 0;

  virtual void copyRecord(CdoStreamID dest) = 0;

  virtual int inqTimestep(int tsID) = 0;
  virtual void defTimestep(int tsID) = 0;

  virtual int inqFileType() = 0;
  virtual int inqByteorder() = 0;

  virtual void close() = 0;

  virtual size_t getNvals() = 0;

  int getID();
  int getTsID();
  int getVarID();
  int getVlistID();

  int m_cdoStreamID;  // aka the id of the pstream
  int m_filetype;
  size_t m_nvals;
  bool isopen;

  std::string m_name;
  std::vector<Datarange> m_datarangelist;

  int m_vlistID;
  int m_tsID;
  int m_varID; // next varID defined with streamDefVar

  // to be removed or to be moved to FileStream! // some operators need some refactoring for these to be able to be moved
  int m_fileID;
  bool ispipe;

protected:
  CdoStream();
  virtual ~CdoStream() = 0;
  void defDatarangeList(int p_vlistID);

private:
};

#endif /* CDOSTREAM_H */
