/*
 * 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.
 */


#include "output.hh"
#include "configuration.hh"
#include "posexcept.hh"

#include "outputterminal.hh"
#include "outputcsv.hh"
#include "outputudpsocket.hh"
#include "outputtcpsocketevaal.hh"

#include <string>

using namespace std ;



/* *** Constructors *** */


Output::Output()
{
  initialise_output_media() ;
}


Output::~Output()
{
  for (auto i = output_media.begin() ; i != output_media.end() ; ++i)
    delete *i ;
  output_media.clear() ;
}



/* *** Operations *** */


void Output::initialise_output_media()
{
  if (! Configuration::is_configured("output.medium"))
    {
      initialise_output_terminal() ;
      return ;
    }

  const vector<string> &media_names =
    Configuration::string_vector_value("output.medium") ;

  for (auto i = media_names.begin() ; i != media_names.end() ; ++i)
    {
      if (*i == "Terminal")
        initialise_output_terminal() ;

      else if (*i == "CSV")
        initialise_output_csv() ;

      else if (*i == "UDP")
        initialise_output_udp_socket() ;

      else if (*i == "TCPEvAAL")
        initialise_output_tcpevaal_socket() ;

      else
        throw bad_configuration(
          "The specified output medium \""+ *i +"\" is unknown!") ;
    }
}


void Output::initialise_output_terminal()
{
  output_media.push_back(new OutputTerminal) ;
}


void Output::initialise_output_csv()
{
  if (! Configuration::is_configured("output.csv-file"))
    throw missing_configuration(
      "No output CSV file specified in the configuration!") ;

  output_media.push_back(
    new OutputCSV(
      Configuration::string_value("output.csv-file"))) ;
}


void Output::initialise_output_udp_socket()
{
  if (! Configuration::is_configured("output.udp-host"))
    throw missing_configuration(
      "No remote UDP host specified in the configuration!") ;

  output_media.push_back(
    new OutputUDPSocket(Configuration::string_value("output.udp-host"),
                        Configuration::int_value("output.udp-port"))) ;
}


void Output::initialise_output_tcpevaal_socket()
{
  output_media.push_back(
    new OutputTCPSocketEvAAL(
      Configuration::string_value("output.tcpevaal-host"),
      Configuration::int_value("output.tcpevaal-port"))) ;
}


void Output::write(const ResultList &results) const
{
  for (auto i = output_media.begin() ; i != output_media.end() ; ++i)
    (*i)->write(results) ;
}
