/*
 *  MICO --- a free CORBA implementation
 *  Copyright (C) 1997-98 Kay Roemer & Arno Puder
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *  Send comments and/or bug reports to:
 *                 mico@informatik.uni-frankfurt.de
 */

#include <sys/types.h>
#include <signal.h>
#include <iostream.h>
#include <fstream.h>
#include <CORBA.h>
#include <mico/util.h>
#include <mico/template_impl.h>
#include "mediator.h"
#include "poamediator.h"

CORBA::ORB_ptr orb;
CORBA::BOA_ptr boa;
CORBA::OAMediator_ptr med;
CORBA::POAMediator_ptr pmd;
string thedb;

int
save_imr (const char *fn)
{
    ofstream out (fn);
    if (!out) {
	cerr << "error: cannot open output file " << fn << endl;
	return 1;
    }
    CORBA::ImplRepository_var imr = CORBA::ImplRepository::_narrow (
	orb->resolve_initial_references ("ImplementationRepository"));

    CORBA::ImplRepository::ImplDefSeq_var impls = imr->find_all();
    for (CORBA::ULong i = 0; i < impls->length(); ++i) {
	CORBA::String_var s = impls[i]->command();
	if (strlen (s) > 0) {
	    // it is not an automatically created entry
	    s = impls[i]->tostring();
	    out << s.in() << endl;
	}
    }
    return 0;
}

int
restore_imr (const char *fn)
{
    ifstream in (fn);
    if (!in) {
	cerr << "warning: cannot open input file " << fn << endl;
	return 1;
    }
    CORBA::ImplRepository_var imr = CORBA::ImplRepository::_narrow (
	orb->resolve_initial_references ("ImplementationRepository"));

    char line[10000];
    while (!in.getline (line, sizeof (line)).eof()) {
	CORBA::ImplementationDef_var impl = imr->restore (line);
	assert (!CORBA::is_nil (impl));
    }
    return 0;
}

void
sighandler (int sig)
{
    if (thedb.length() > 0)
	save_imr (thedb.c_str());
    if (!CORBA::is_nil (med))
	CORBA::release (med);
    signal (sig, SIG_DFL);
    raise (sig);
}

void
usage (const char *progname)
{
    cerr << "usage: " << progname << " [<options>]" << endl;
    cerr << "possible <options> are:" << endl;
    cerr << "    --help" << endl;
    cerr << "    --db <database file>" << endl;
    exit (1);
}

int
main (int argc, char *argv[])
{
    orb = CORBA::ORB_init (argc, argv, "mico-local-orb");
    boa = orb->BOA_init (argc, argv, "mico-local-boa");
    pmd = new POAMediatorImpl (orb);
    med = new MediatorImpl;

    MICOGetOpt::OptMap opts;
    opts["--help"] = "";
    opts["--db"]   = "arg-expected";

    MICOGetOpt opt_parser (opts);
    if (!opt_parser.parse (argc, argv))
	usage (argv[0]);

    for (MICOGetOpt::OptVec::const_iterator i = opt_parser.opts().begin();
	 i != opt_parser.opts().end(); ++i) {
	string arg = (*i).first;
	string val = (*i).second;

	if (arg == "--db") {
	    thedb = val;
	} else if (arg == "--help") {
	    usage (argv[0]);
	} else {
	    usage (argv[0]);
	}
    }
    if (argc != 1) {
	usage (argv[0]);
    }

    if (thedb.length() > 0)
	restore_imr (thedb.c_str());

    signal (SIGTERM, sighandler);
    signal (SIGINT, sighandler);
#ifndef _WINDOWS
    signal (SIGHUP, sighandler);
#endif

    orb->run ();
    // notreached
    return 0;
}
