#include "Dim.h"
#include "Configuration.h"
#include "RemoteControl.h"

using namespace std;

template <class T>
void RunShell(Configuration &conf)
{
    // A normal kill will call its destructor! (Very nice feature ;) )
    static T shell(conf.GetName().c_str(),
                   conf.Has("console") ? conf.Get<int>("console")!=1 : conf.Get<bool>("null"));

    WindowLog &win  = shell.GetStreamIn();
    WindowLog &wout = shell.GetStreamOut();

    if (conf.Has("log"))
        if (!wout.OpenLogFile(conf.Get<string>("log"), conf.Get<bool>("append-log")))
            win << kRed << "ERROR - Couldn't open log-file " << conf.Get<string>("log") << ": " << strerror(errno) << endl;

    const vector<string> v1 = conf.Vec<string>("cmd");
    for (vector<string>::const_iterator it=v1.begin(); it!=v1.end(); it++)
        shell.ProcessLine(*it);

    const vector<string> v2 = conf.Vec<string>("exec");
    for (vector<string>::const_iterator it=v2.begin(); it!=v2.end(); it++)
        shell.Execute(*it);

    if (conf.Get<bool>("quit"))
        shell.Stop();

    shell.Run();
}


// ========================================================================

/*
 Extract usage clause(s) [if any] for SYNOPSIS.
 Translators: "Usage" and "or" here are patterns (regular expressions) which
 are used to match the usage synopsis in program output.  An example from cp
 (GNU coreutils) which contains both strings:
  Usage: cp [OPTION]... [-T] SOURCE DEST
    or:  cp [OPTION]... SOURCE... DIRECTORY
    or:  cp [OPTION]... -t DIRECTORY SOURCE...
 */
void PrintUsage()
{
    cout << "\n"
        "The console connects to all available Dim Servers and allows to "
        "easily access all of their commands.\n"
        "\n"
        "Usage: dimctrl [-c type] [OPTIONS]\n"
        "  or:  dimctrl [OPTIONS]\n";
    cout << endl;

}

void PrintHelp()
{
    /* Additional help text which is printed after the configuration
     options goes here */
}

#include "Main.h"

int main(int argc, const char *argv[])
{
    Configuration conf(argv[0]);
    conf.SetPrintUsage(PrintUsage);
    Main::SetupConfiguration(conf);

    if (!conf.DoParse(argc, argv, PrintHelp))
        return -1;

    Dim::Setup(conf.Get<string>("dns"), conf.Get<string>("host"));

    if (!conf.Has("console"))
        //Main<RemoteShell, DummyService>(conf);
        RunShell<RemoteShell>(conf);
    else
        //Main<RemoteConsole, DummyService>(conf);
        RunShell<RemoteConsole>(conf);


    return 0;
}
