//
// Created by rhetenor on 5/21/19.
//

#ifndef FLIPPR_DRIVER_FLIPPRSERVER_H
#define FLIPPR_DRIVER_FLIPPRSERVER_H

#include "output/OutputDriver.h"
#include "input/InputDriver.h"

#include <Poco/Util/ServerApplication.h>
#include <Poco/Net/HTTPServer.h>
#include <Poco/Dynamic/Struct.h>
#include <Poco/File.h>

namespace flippR_driver
{
namespace networking
{

class FlippRServer : public Poco::Util::ServerApplication
{
public:
  FlippRServer();

  int main(const std::vector<std::string>& args);

  void initialize(Poco::Util::Application& self);
  void uninitialize();

  void defineOptions(Poco::Util::OptionSet& options);
  void handle_help(const std::string &name, const std::string &port);
  void handle_config_file(const std::string &name, const std::string &value);

private:
  void initialize_output_driver();
  void initialize_input_driver();

  void parse_server_config_file();

  std::string get_runtime_dir();
  Poco::Net::HTTPServer* build_output_server();
  Poco::Net::TCPServer* build_input_server();

private:
  const char * DEFAULT_RUNTIME_DIR = "/tmp/";
  const char * INPUT_SOCKET_NAME = "S.flippR_driver.in";
  const char * OUTPUT_SOCKET_NAME = "S.flippR_driver.out";
  const std::vector<std::string> REQUIRED_CONFIG_KEYS = {"display-config", "input-config", "lamp-config",
                                                         "matrix-config", "solenoid-config", "sound-config"};
  int input_port;
  int output_port;

  bool help_requested;

  Poco::DynamicStruct configs;

  std::string server_config;

  std::shared_ptr<input::InputDriver> input_driver;
  std::shared_ptr<output::OutputDriver> output_driver;

  std::unique_ptr<Poco::Net::HTTPServer> output_server;
  std::unique_ptr<Poco::Net::TCPServer> input_server;

  Poco::File output_socket_file, input_socket_file;

};

};
}


#endif //FLIPPR_DRIVER_FLIPPRSERVER_H
