// mdconfiguration.cpp
// SNF MDaemon Plugin: Platform Configuration Module
// Copyright (C) 2007-2008, ARM Research Labs, LLC.

#include "mdconfiguration.hpp"

MDConfiguration::MDConfiguration(snf_RulebaseHandler& R, string& C) :           // Default constructor.
  MyCFGReader("mdaemon"),                                                       // The top element is "mdaemon"
  MyGeneration(-1),                                                             // Our first real gen will be 0.
  MyMessageIPFuncOn(true),                                                      // By default the IP func is on.
  MyConfiguratorCommand("start notepad"),                                       // By default we start notepad to
  MyAppendConfigurationFileOn(true),                                            // edit our config and pass it the path.
  MyConfigurationPath(C),                                                       // This is the config file path.
  MyRulebase(R) {                                                               // This is the rulebase manager.

  // Here we construct the configuration elements that will parse the platform
  // configuration data from our rulebase manager.

    MyCFGReader
        .Element("ip-test")
            .Attribute("on-off", MyMessageIPFuncOn, false)
        .End("ip-test")
        .Element("configurator")
            .Attribute("command", MyConfiguratorCommand, "")
            .Attribute("append-path", MyAppendConfigurationFileOn, true)
        .End("configurator")
    .End("mdaemon");
}

int MDConfiguration::Generation() {                                             // When checking our generation we
    return MyGeneration;                                                        // need only return what we have.
}

bool MDConfiguration::MessageIPFuncOn() {                                       // Are we using the MessageIP function?
    ScopeMutex EverybodyFreeze(MyMutex);                                        // Freeze the mutex.
    updateConfig();                                                             // Update the configuration if needed.
    return MyMessageIPFuncOn;                                                   // Return the IP Func On/Off value.
}

string MDConfiguration::ConfiguratorCommand() {                                 // Return proper configurator command.
    ScopeMutex EverybodyFreeze(MyMutex);                                        // Freeze the mutex.
    updateConfig();                                                             // Update the configuration.
    string ConfiguratorCommandString = "";                                      // Keep this in scope.
    if(0 < MyConfiguratorCommand.length()) {                                    // If we have a command configured:
        ConfiguratorCommandString = MyConfiguratorCommand;                      // capture that command.
        if(MyAppendConfigurationFileOn) {                                       // If we are supposed to append the
            ConfiguratorCommandString.append(" ");                              // configuration file path then
            ConfiguratorCommandString.append(MyConfigurationPath);              // tack that on the end.
        }                                                                       // If the configure command string was
    }                                                                           // configured empty we will return "".
    return ConfiguratorCommandString;                                           // Send back what we got.
}

void MDConfiguration::updateConfig() {                                          // Parse & update the config if needed.
    if(MyGeneration != MyRulebase.Generation()) {                               // If our config is out of sync:
        try {                                                                   // Catch any parsing errors.
            string NewConfiguration = MyRulebase.PlatformConfiguration();       // Grab the configuration string.
            ConfigurationData MyConfigData(                                     // Load the configuration string
              NewConfiguration.c_str(), NewConfiguration.length());             // into a configuration data object.
            MyCFGReader.initialize();                                           // Initialize the parser and
            MyCFGReader.interpret(MyConfigData);                                // feed it the object.
            MyGeneration = MyRulebase.Generation();                             // Grab the new generation tag.
        }
        catch(...) { }                                                          // Eat any thrown exceptions.
    }                                                                           // If we're in sync we don't budge.
}


