// snf_sync.hpp
// Copyright (C) 2006 - 2009 ARM Research Labs, LLC.
// See www.armresearch.com for the copyright terms.
//
// SNF engine communications protocol interpreter.
// Communications are well formed xml snippets.
// See snf_sync.xml for examples.

#ifndef snf_sync_included
#define snf_sync_included

#include <list>
#include <cstring>
#include "GBUdb.hpp"
#include "networking.hpp"
#include "configuration.hpp"

class GBUAlertHandler : public Configurator {
  public:
    virtual void operator()(ConfigurationElement& E, ConfigurationData& D);     // Add an alert handler :-)

    void reset();                                                               // Resets the list for a new run.

    list<GBUdbAlert> AlertList;                                                 // Our list of alerts.

    // Input variables.

    string Alert_time;                                                          // time='YYYYMMDDhhmmss'
    string Alert_ip;                                                            // ip='12.34.56.78'
    string Alert_t;                                                             // t='Ugly', Good, Bad, Ignore
    int Alert_b;                                                                // b='0'
    int Alert_g;                                                                // g='0'
};

class GBUAlertInitializer : public Configurator {
  private:
    GBUAlertHandler* MyHandler;                                                 // Handler to reset.

  public:
    GBUAlertInitializer() { MyHandler = NULL; }                                 // Init safely with null.
    void link(GBUAlertHandler& H) { MyHandler = &H; }                           // Link to my handler.
    virtual void operator()(ConfigurationElement& E, ConfigurationData& D) {    // Add an alert handler :-)
        if(NULL != MyHandler) {                                                 // If I know where it is
            MyHandler->reset();                                                 // I hit the reset button.
        }
    }
};

class snf_sync {
  private:
    ConfigurationElement Reader;                                                // Our reader.
    void SetupReader();                                                         // Configure the reader.
    ConfiguratorSetTrueOnComplete SNFWasParsed;                                 // Configurator sets the ReadWasGood
    bool ReadWasGood;                                                           // flag at the end of the snf element.
    void construct();                                                           // Encapsulate the initial construction.
    void reset();                                                               // Reset/initialize for the next read.

  public:
    snf_sync();                                                                 // Construct empty.
    snf_sync(const char* bfr, int len);                                         // Construct from buffer.
    snf_sync(string& input);                                                    // Construct from string.
    bool read(const char* bfr, int len);                                        // Read from buffer.
    bool read(string& input);                                                   // Read from string.

    //// And now the interpreted results ////
    bool good();                                                                // True if read was good.
    bool bad();                                                                 // True if read was not good.

    string snf_sync_challenge_txt;
    string snf_sync_response_nodeid;
    string snf_sync_response_text;
    string snf_sync_error_message;
    int snf_sync_error_code;
    string snf_sync_rulebase_utc;
    int snf_sync_server_resync_secs;

    GBUAlertHandler ClientGBUAlertHandler;                                      // GBU Alerts received from client
    GBUAlertInitializer ClientGBUAlertInitializer;

    GBUAlertHandler ServerGBUAlertHandler;                                      // GBU Alerts received from server
    GBUAlertInitializer ServerGBUAlertInitializer;
};

#endif

