// snfLOGmgr.inline.hpp
//
// (C) Copyright 2006 - 2009 ARM Research Labs, LLC.
// Inline methods for the snfLOGmgr

//// snfScanData ///////////////////////////////////////////////////////////////

inline int snfScanData::IPScanCount() {                                         // Return the number of IPs.
    return MyIPCount;
}

inline IPScanRecord& snfScanData::newIPScanRecord() {                           // Get the next free IP scan record.
    if(MaxIPsPerMessage <= MyIPCount) {                                         // Check that we have more records.
        throw NoFreeIPScanRecords();                                            // If we do not then throw!
    }                                                                           // If we do have more records then
    IPScanRecord& NewRecord = MyIPScanData[MyIPCount];                          // Pick the next available one,
    NewRecord.Ordinal = MyIPCount;                                              // set the ordinal value,
    ++MyIPCount;                                                                // increase our count, and
    return NewRecord;                                                           // return the one we picked.
}

inline IPScanRecord& snfScanData::IPScanData(int i) {                           // Return the IP scan record i.
    if(MyIPCount <= i || 0 > i) {                                               // First check that i is in bounds.
        throw OutOfBounds();                                                    // if it is not then throw!
    }                                                                           // If the record for [i] is available
    return MyIPScanData[i];                                                     // return it.
}

inline void snfScanData::drillPastOrdinal(int O) {                              // Sets Drill Down flag for IP record O.
    if(0 <= O && O < MaxIPsPerMessage) {                                        // If O is a useable Received ordinal
        DrillDownFlags[O] = true;                                               // then set the Drill Down Flag for O.
    }
}

inline bool snfScanData::isDrillDownSource(IPScanRecord& X) {                   // True if we drill through this source.
    if(
      (0UL != myCallerForcedSourceIP) ||                                        // If the source IP has been forced by
      (0UL != myHeaderDirectiveSourceIP)                                        // the caller or by a header directive
      ) return false;                                                           // then drilldowns are disabled.
                                                                                // Otherwise check for a drilldown flag.
    return DrillDownFlags[X.Ordinal];                                           // Presuming X is valid, return the flag.
}                                                                               // If X is not valid we may blow up!

inline IPScanRecord& snfScanData::SourceIPRecord(IPScanRecord& X) {             // Sets the source IP record.
    SourceIPOrdinal = X.Ordinal;                                                // Here's the ordinal.
    SourceIPFoundFlag = true;                                                   // Here's the truth flag.
}

inline IPScanRecord& snfScanData::SourceIPRecord() {                            // Gets the source IP record.
    return IPScanData(SourceIPOrdinal);                                         // Return the IP record, or throw
}                                                                               // OutOfBounds.

inline bool snfScanData::FoundSourceIP() {                                      // True if the source IP record was set.
    return SourceIPFoundFlag;                                                   // Return what the flag says.
}

inline snfIPRange snfScanData::SourceIPRange(snfIPRange R) {                    // Establish the IP range.
    return (SourceIPRangeFlag = R);                                             // set and return the value w/ R.
}

inline snfIPRange snfScanData::SourceIPRange() {                                // Gets the source IP detection range.
    return SourceIPRangeFlag;                                                   // Return what the flag says.
}

inline IP4Address snfScanData::HeaderDirectiveSourceIP(IP4Address A) {          // set Header directive source IP.
    if(0UL == myHeaderDirectiveSourceIP) myHeaderDirectiveSourceIP = A;         // If this value is not set, set it.
    return myHeaderDirectiveSourceIP;                                           // Return the value.
}

inline IP4Address snfScanData::HeaderDirectiveSourceIP() {                      // get Header directive source IP.
    return myHeaderDirectiveSourceIP;                                           // Return the current value.
}

inline IP4Address snfScanData::CallerForcedSourceIP(IP4Address A) {             // set Caller forced source IP.
    if(0UL == myCallerForcedSourceIP) myCallerForcedSourceIP = A;               // If this value is not set, set it.
    return myCallerForcedSourceIP;                                              // Return the value.
}

inline IP4Address snfScanData::CallerForcedSourceIP() {                         // get Caller forced source IP.
    return myCallerForcedSourceIP;                                              // Return the current value.
}

//// snfLOGmgr /////////////////////////////////////////////////////////////////

inline void snfLOGmgr::updateActiveUTC(string ActiveUTC) {                      // Update Active Rulebase UTC.
    ScopeMutex Freeze(MyMutex);                                                 // Protect the strings.
    ActiveRulebaseUTC = ActiveUTC;                                              // Update the active timestamp.
    NewerRulebaseIsAvailable = false;                                           // Update availability is now unknown.
}

inline void snfLOGmgr::updateAvailableUTC(string& AvailableRulebaseTimestamp) { // Changes update avialability stamp.
    ScopeMutex Freeze(MyMutex);                                                 // Protect the strings.
    AvailableRulebaseUTC = AvailableRulebaseTimestamp;                          // Store the new timestamp.
    if(0 < AvailableRulebaseUTC.compare(ActiveRulebaseUTC)) {                   // If the available timestamp is newer
        NewerRulebaseIsAvailable = true;                                        // than the active then set the flag.
    } else {                                                                    // If it is not newer then
        NewerRulebaseIsAvailable = false;                                       // reset the flag.
    }
}

inline string snfLOGmgr::ActiveRulebaseTimestamp() {                            // Get active rulebase timestamp.
    ScopeMutex Freeze(MyMutex);                                                 // Protect the string.
    return ActiveRulebaseUTC;                                                   // Return it.
}

inline string snfLOGmgr::AvailableRulebaseTimestamp() {                         // Get available rulebase timestamp.
    ScopeMutex Freeze(MyMutex);                                                 // Protect the strings.
    return AvailableRulebaseUTC;                                                // Return the available timestamp.
}

inline bool snfLOGmgr::isUpdateAvailable() {                                    // True if update is available.
    return NewerRulebaseIsAvailable;                                            // Return the flag's value.
}

inline int snfLOGmgr::LatestRuleID() {                                          // Query the latest rule id.
    return Status.LatestRuleID;                                                 // This simple value is atomic
}                                                                               // so we can read it without the mutex.

inline int snfLOGmgr::RunningTime() {                                           // Get the time we've been alive.
    return (int) difftime(Timestamp(), StartupTime);
}
