#include "SecGame.hh"
#include "Registry.hh"

#include <fstream>
#include <getopt.h>

#include <sys/types.h>
#include <unistd.h>


using namespace std;



void help (int argc, char** argv) {
    cout << "Usage: " << argv[0] << " [options] player1 player2 ... [< start.cnf] [> game.out] " << endl;
    cout << "Available options:" << endl;
    cout << "--player=pl\t-p player\t\tset child player number" << endl;
    cout << "--seed=seed\t-s seed\t\tset random seed" << endl;
    cout << "--input=file\t-i input\tset input file" << endl;
    cout << "--output=file\t-o output\tset output file" << endl;
    cout << "--result=file\t-r file\t\tset results file" << endl;
    cout << "--list\t\t-l\t\tlist registered players" << endl;
    cout << "--version\t-v\t\tprint version" << endl;
    cout << "--help\t\t-h\t\tprint help" << endl;
}


void version () {
    cout << Board::version() << endl;
    cout << "compiled " << __TIME__ << " " << __DATE__ << endl;
}




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

    if (argc == 1) {
        help(argc, argv);
        return EXIT_SUCCESS;
    }

/*
    cerr << "Call: ";
    for (int i = 0; i < argc; i++) cerr << argv[i] << " ";
    cerr << endl
*/

    struct option long_options[] = {
        {"player",         required_argument,  0, 'p'},
        {"seed",           required_argument,  0, 's'},
        {"input",          required_argument,  0, 'i'},
        {"output",         required_argument,  0, 'o'},
        {"result",         required_argument,  0, 'r'},
        {"list",           no_argument,        0, 'l'},
        {"version",        no_argument,        0, 'v'},
        {"help",           no_argument,        0, 'h'},
        {0, 0, 0, 0}
    };

    int player = -1;
    char* ifile = 0;
    char* ofile = 0;
    char* rfile = 0;
    int seed = -1;
    vector<string> args;

    while (true) {
        int option_index = 0;
        int c = getopt_long(
            argc, argv,
            "p:s:i:o:r:lvh",
            long_options, &option_index
        );

        if (c == -1) break;

        switch (c) {

            case 'p':
                player = s2i(optarg);
                break;

            case 's':
                seed = s2i(optarg);
                break;

            case 'i':
                ifile = optarg;
                break;

            case 'o':
                ofile = optarg;
                break;

            case 'r':
                rfile = optarg;
                break;

            case 'l':
                Registry::print_players(cout);
                return EXIT_SUCCESS;

            case 'v':
                version();
                return EXIT_SUCCESS;

            case 'h':
                help(argc, argv);
                return EXIT_SUCCESS;

            default:
                return EXIT_FAILURE;
    }   }

    while (optind < argc) {
        args.push_back(argv[optind++]);
    }

    if (seed < 0) seed = time(0) * (43625 + getpid());
    srand(seed);


    if (player == -1) {

        // master
        istream* is = ifile ? new ifstream(ifile) : &cin ;
        ostream* os = ofile ? new ofstream(ofile) : &cout;
        ostream* rs = rfile ? new ofstream(rfile) : &cerr;

        SecGame::run_master(args, *is, *os, *rs);

        if (ifile) delete is;
        if (ofile) delete os;
        if (rfile) delete rs;

    } else {

        // child
        cerr << "Hello from child " << player << endl;
        if (sze(args) != 3) myerrx("wrong number of parameters.");
        SecGame::run_child(player, args[0], args[1], args[2]);

    }
}


