// main.cpp
//
// Copyright (C) 2012, ARM Research Labs, LLC.
// See www.armresearch.com for the copyright terms.
//
// Create and maintain the sniffer configuration file for SNFServer.
//
// The configuration file and instructions are specified on the
// command line, and are used to create/modify the configuration file,
// and integrate or unintegrate with the specified MTA.
//
//
// $Id$
//
///////////////////////////////////////////////////////////////////////////////////////////////////

#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
#include <sys/stat.h>

#include <exception>
#include <iostream>
#include <fstream>

#include "SNFMulti.hpp"
#include "SNFServerConfig.hpp"

using namespace std;

//////////////////////////////////////////////////////////////////////////////////////////////////////////
// Configuration. ////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////

/// Version string.
const char* SNF_SERVERCONFIG_VERSION = "SNFServerConfig 0.0.1 Build: " __DATE__ " " __TIME__;

//////////////////////////////////////////////////////////////////////////////////////////////////////////
// End of configuration. /////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////

void RestoreFiles(SNFServerConfig *Config) {

    try {

        cerr << "Restoring all configuration files...";

        Config->SaveFile.RestoreAllFilesFromBackup();

        Config->SetOwnerPermissionsOfConfigFiles();

        cerr << "done.\n\n"
             << "Configuration files that resulted in this error are saved with a suffix \""
             << Config->SaveFile.GetFailedFileName("") << "\".\n";
    }
    catch(exception& e) {

        cerr << "SNFServerConfig::SaveFile Exception: " << e.what() << endl;

    }

}

int main(int argc, char* argv[]) {

    SNFServerConfig SnfServerConfig;

    try {                                                                       // Catch anything that breaks loose.

        if (!SnfServerConfig.GetCommandLineInput(argc, argv) ||                 // If our command line arguments
            SnfServerConfig.Help()) {                                           // don't look right, or if help is
                                                                                // requested  then display our help
            SnfServerConfig.DisplayHelp(SNF_SERVERCONFIG_VERSION);              // screen.
            return 0;

        }

        bool DebugMode = false;                                                 // This will be our debug mode.
        string argv0(argv[0]);                                                  // Capture how we were called.
        if(
           string::npos != argv0.find("Debug") ||                               // If we find "Debug" or
           string::npos != argv0.find("debug")                                  // "debug" in our command path
           ) {                                                                  // then we are in DebugMode.
            DebugMode = true;                                                   // Set the flag and tell the
            cout << SNF_SERVERCONFIG_VERSION << endl;                           // watchers.
            cout << "Debug Mode" << endl;
            SnfServerConfig.SetDebug(true);
        }

        SnfServerConfig.ExecuteCommand();

    }                                                                           // That's all folks.

    catch(exception& e) {                                                       // Report any normal exceptions.
        cerr << "\n\nSNFServerConfig Exception: " << e.what() << endl << endl;
        RestoreFiles(&SnfServerConfig);
        return(-1);
    }
    catch (snfCFGmgr::LoadFailure) {                                            // Error loading configuration file.
        cerr << "\n\nsnfCFGmgr Exception:  Unable to load the configuration file "
             << SnfServerConfig.GetConfigFileName() << endl << endl;
        RestoreFiles(&SnfServerConfig);
        return(-1);
    }
    catch(...) {                                                                // Report any unexpected exceptions.
        cerr << "\n\nSNFServerConfig Panic! Unknown Exception!" << endl << endl;
        RestoreFiles(&SnfServerConfig);
        return(-1);
    }

    return 0;                                                                   // Normally we return zero.

}