/*
 * This file is part of the Owl Positioning System (OwlPS) project.
 * It is subject to the copyright notice and license terms in the
 * COPYRIGHT.t2t file found in the top-level directory of this
 * distribution and at
 *   https://code.lm7.fr/mcy/owlps/src/master/COPYRIGHT.t2t
 * No part of the OwlPS Project, including this file, may be copied,
 * modified, propagated, or distributed except according to the terms
 * contained in the COPYRIGHT.t2t file; the COPYRIGHT.t2t file must be
 * distributed along with this file, either separately or by replacing
 * this notice by the COPYRIGHT.t2t file's contents.
 */


#ifndef _OWLPS_POSITIONING_INPUTCSV_HH_
#define _OWLPS_POSITIONING_INPUTCSV_HH_

#include "inputmedium.hh"
#include "csvfilereader.hh"
#include "configuration.hh"

#include <string>
#include <iostream>

/// Reads [requests](@ref Request) from a CSV file
/**
 * CSV format is:
 *     Format_version;Mobile_MAC;Request_type;Number_of_packets;
 *     Timestamp;X;Y;Z;Direction;CP_MAC_1;Packet_ID_1;SS_1;…;
 *     CP_MAC_n;Packet_ID_n;SS_n
 */
class InputCSV: public InputMedium
{
protected:
  CSVFileReader file ;

  /** @name Operations */
  //@{
  /// Reads data & fills the current request
  bool fill_current_request(void) ;
  /// Reads a field and handle error message printing
  template<class T> bool read_field(T &field,
                                    const std::string &message) ;
  //@}

public:
  explicit InputCSV(const std::string &filename):
    file(filename) {}

  ~InputCSV(void) {}

  /** @name Read accessors */
  //@{
  /// Checks if the end of the CSV file has been reached
  bool eof(void) const ;
  //@}

  /** @name Operators */
  //@{
  operator bool(void) const ;
  //@}
} ;



/* *** Read accessors *** */


inline bool InputCSV::eof() const
{
  return file.eof() ;
}



/* *** Operations *** */


/**
 * This functions tries to read `field` from the input CSV file; if it
 * fails and the verbose mode is active, a message is displayed on the
 * standard error.
 *
 * @param field The variable in which the read field will be stored.
 * @param message The name of the field to be displayed in case of error.
 *
 * @returns `true` in case of success.
 * @returns `false` in case of error.
 */
template<class T>
inline bool InputCSV::read_field(T &field, const std::string &message)
{
  if (file.read_field(field))
    return true ;

  // Wrong number of fields
  if (Configuration::is_configured("verbose"))
    std::cerr << "InputCSV: cannot read " << message << ".\n" ;

  return false ;
}



/* *** Operators *** */


inline InputCSV::operator bool() const
{
  return ! eof() ;
}



#endif // _OWLPS_POSITIONING_INPUTCSV_HH_
