/** \file
 *
 *  Main.
 *
 *  Copyright (c) 2007 MBARI
 *  MBARI Proprietary Information.  All Rights Reserved
 *
 */

#include "data/Slate.h"
#include "supervisor/Supervisor.h"
#include "utils/Str.h"

#include <stdlib.h>
#include <unistd.h>

/**
 *  The entry point for the software.  Creates a supervisor and runs it.
 */
int main( int argc, char **argv );
bool run_code( int argc, char **argv );

int main( int argc, char **argv )
{
    if( run_code( argc, argv ) )
    {
        if( Supervisor::IsRestart() )
        {
            int newArgc = Supervisor::GetArgc();
            char** newArgv = Supervisor::GetArgv();
            switch( newArgc )
            {
            case 1:
                execl( argv[0], argv[0], NULL );
                break;
            case 2:
                execl( argv[0], argv[0], newArgv[1], NULL );
                break;
            case 3:
                execl( argv[0], argv[0], newArgv[1], newArgv[2], NULL );
                break;
            case 4:
                execl( argv[0], argv[0], newArgv[1], newArgv[2], newArgv[3], NULL );
                break;
            case 5:
                execl( argv[0], argv[0], newArgv[1], newArgv[2], newArgv[3], newArgv[4], NULL );
                break;
            case 6:
                execl( argv[0], argv[0], newArgv[1], newArgv[2], newArgv[3], newArgv[4], newArgv[5], NULL );
                break;
            case 7:
                execl( argv[0], argv[0], newArgv[1], newArgv[2], newArgv[3], newArgv[4], newArgv[5], newArgv[6], NULL );
                break;
            }
        }
    }

    Supervisor::ClearArgs();

    return 0;
}

bool run_code( int argc, char **argv )
{
    Supervisor::TouchRunningFile();

    Str logSymlinkSubdir = "";
    for( int i = 0; i + 1 < argc; ++i )
    {
        if( NULL != argv[ i ] && *argv[ i ] == '-' )
        {
            for( int j = 1; 0 != argv[ i ][ j ]; ++j )
            {
                if( argv[ i ][ j ] == 'l' )
                {
                    logSymlinkSubdir = argv[ i + 1 ];
                    break;
                }
                if( argv[ i ][ j ] == 'p' )
                {
                    sleep( atoi( argv[ i + 1 ] ) );
                    break;
                }
#ifdef __FASTSIM
                if( argv[ i ][ j ] == 't' )
                {
                    Timestamp::SetNow( Timestamp( argv[ i + 1 ] ) );
                    break;
                }
#endif
            }
        }
    }

    Str dataDir = Supervisor::GenerateDataDir( logSymlinkSubdir );
    Slate::ReadDirectory( dataDir + "/slate.dir" );
    Slate::EnableDirectoryWrites();

    Supervisor supervisor( argc, argv, dataDir );

    supervisor.initialize();
    supervisor.run();
    supervisor.uninitialize();

    // This leaves a newline when the program exits, to avoid garbling the command line when it is wider than the current terminal.
    printf( "\n" );

    return true;
}
