// snfNETmgr.hpp
//
// (C) Copyright 2006 - 2009 ARM Research Labs, LLC.
// See www.armresearch.com for the copyright terms.
//
// SNF network node manager.

// 20080312 _M Refactored exceptions to std::runtime_exception

#ifndef snfNETmgr_included
#define snfNETmgr_included

#include <stdexcept>
#include <vector>
#include "networking.hpp"
#include "timing.hpp"
#include "threading.hpp"
#include "snfCFGmgr.hpp"
#include "snfLOGmgr.hpp"
#include "snfGBUdbmgr.hpp"
#include "mangler.hpp"

class snfScanData;                                                              // Declare snfScanData;
class snfLOGmgr;                                                                // Declare snfLOGmgr;
class snfGBUdbmgr;                                                              // Declare snfGBUdbmgr;

using namespace std;

typedef vector<unsigned char> PadBuffer;                                        // Holds one time pads etc.
const int SNFHandshakeSize = 8;                                                 // Size of an SNF Handshake.
const int SNFChallengeSize = 32;                                                // Size of an SNF Challenge.
const int SNFPadSize = 16;                                                      // Size of an SNF One Time Pad.
const int SNFSignatureSize = SNFHandshakeSize;                                  // Size of an SNF Signature.

class snfNETmgr : public Thread {                                               // The network process manager.
  private:

    Mutex myMutex;                                                              // Object is busy mutex.
    Mutex ResolverMutex;                                                        // Mutex to protect lookups.
    Mutex ConfigMutex;                                                          // Configuration change/use mutex.
    Mutex PadMutex;                                                             // Pad use/evoloution mutex.

    snfLOGmgr* myLOGmgr;                                                        // Log manager to use.
    snfGBUdbmgr* myGBUdbmgr;                                                    // GBUdb manager to use.

    volatile bool isTimeToStop;                                                 // Time to shutdown flag.
    volatile bool isConfigured;                                                 // True once ready to run.

    Timeout SYNCTimer;                                                          // SYNC timer.

    void evolvePad(string Entropy = "");                                        // Add entropy to and evolve.
    MANGLER PadGenerator;                                                       // Random pad source.
    PadBuffer OneTimePad(int Len = SNFPadSize);                                 // Provides Len bytes of one time pad.

    // Configuration data

    string License;                                                             // Node (license) Id?
    string SecurityKey;                                                         // Security key for this rulebase?
    string RulebaseFilePath;                                                    // Where we can find our rulebase?
    string HandshakeFilePath;                                                   // Where do we keep our handshake?
    string UpdateReadyFilePath;                                                 // Where do I put update trigger files?
    string SyncHostName;                                                        // Where do we connect to sync?
    int SyncHostPort;                                                           // What port do we use to sync?
    int SyncSecsOverride;                                                       // How may secs between sync (override)?
    int SyncSecsConfigured;                                                     // How many secs to sync (nominally)?

    PadBuffer Handshake();                                                      // What is the current handshake?
    PadBuffer& Handshake(PadBuffer& NewHandshake);                              // Store a new handshake.
    PadBuffer CurrentHandshake;                                                 // Where we keep our current handshake.

    void postUpdateTrigger(string& updateUTC);                                  // Post an update trigger file.

    string SamplesBuffer;                                                       // Message Samples Appended Together.
    string getSamples();                                                        // Syncrhonized way to get Samples.
    string ReportsBuffer;                                                       // Status Reports Appended Together.
    string getReports();                                                        // Synchronized way to get Reports.

  public:

    snfNETmgr();                                                                // Construct and start.
    ~snfNETmgr();                                                               // Shutdown and destruct.

    void stop();                                                                // How to stop the thread.
    void myTask();                                                              // Define the thread task.

    void linkLOGmgr(snfLOGmgr& L);                                              // Set the LOGmgr.
    void linkGBUdbmgr(snfGBUdbmgr& G);                                          // Set the GBUdbmgr.
    void configure(snfCFGData& CFGData);                                        // Update the configuration.

    class SyncFailed : public runtime_error {                                   // Thrown if sync doesn't work.
        public: SyncFailed(const string& w):runtime_error(w) {}
    };

    // Operations

    // Why have configure AND pass CFGData in action calls?
    // The configure() method updates background task configuration itmes.
    // The CFGData passed on action calls informs the configuration in use with
    // that particular operation -- it might be different than the current CFG
    // if the CFG has been updated recently (reload).

    void sendSample(                                                            // Send a sampled message...
      snfCFGData& CFGData,                                                      // Use this configuration,
      snfScanData& ScanData,                                                    // Include this scan data,
      const unsigned char* MessageBuffer,                                       // This is the message itself
      int MessageLength                                                         // and it is this size.
      );

    void sendReport(const string& StatusReportText);                            // Send a status report...

    void sync();                                                                // Do the whole "sync" thing.

    // Utility Functions

    unsigned long ResolveHostIPFromName(const string& N);                       // Find the IP.
    string& RulebaseUTC(string& t);                                             // Gets local rulebase file UTC.

    const static ThreadType Type;                                               // The thread's type.

    const static ThreadState Sleeping;                                          // Taking a break.
    const static ThreadState SYNC_Connect;                                      // Connecting to SYNC server.
    const static ThreadState SYNC_Read_Challenge;                               // Reading challenge.
    const static ThreadState SYNC_Compute_Response;                             // Computing crypto response.
    const static ThreadState SYNC_Send_Response;                                // Sending crypto response.
    const static ThreadState SYNC_Read_Availabilty;                             // Reading rulebase status.
    const static ThreadState SYNC_Send_GBUdb_Alerts;                            // Sending GBUdb alerts.
    const static ThreadState SYNC_Send_Status_Reports;                          // Sending status reports.
    const static ThreadState SYNC_Send_Samples;                                 // Sending message samples.
    const static ThreadState SYNC_Send_End_Of_Report;                           // Sending end of client data.
    const static ThreadState SYNC_Read_Server_Response;                         // Reading server data.
    const static ThreadState SYNC_Close_Connection;                             // Closing connection.
    const static ThreadState SYNC_Parse_GBUdb_Reflections;                      // Parsing GBUdb reflections.
    const static ThreadState SYNC_Log_Event;                                    // Logging SYNC event.

};

#endif