#ifndef lint
static char *RCSid = "$Header: /u/dhay/stan/kent/update/RCS/main.c,v 1.1 91/03/19 23:39:18 dhay Exp Locker: dhay $";
#endif

/*
 * main.c
 *
 * main command loop and initialization
 * for empire tm server
 *
 * Dave Pare, 1986
 */

#include "misc.h"
#include "tm.h"
#include "bit.h"
#include "nat.h"
#include "file.h"
#include "io_mask.h"
#include "io.h"
#ifdef BUDGET
#include "sect.h"
#endif /* BUDGET */

#include <sys/socket.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/un.h>
#include <signal.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <fcntl.h>

extern	int errno;

char	*program = "update";
int	(*leprfunc)();
int	aborted;

long	money[MAXNOC];
long	pops[MAXNOC];
long	sea_money[MAXNOC];
long	air_money[MAXNOC];
natid	cnum = 0;

main(argc, argv)
	int	argc;
	char	**argv;
{
	extern	int etu_per_update;
	extern	double money_res;
	long	now;
	int	etu;
	int	produce;
	int	n;
#ifdef BUDGET
	int	x;
#endif /* BUDGET */
#ifdef SLOW_WAR
	int	cn,cn2,rel;
	struct	natstr *cnp;
#endif /* SLOW_WAR */
	struct	natstr *np;

	if (argc < 3) {
		logerror("usage: %s \"produce|mob\" #etus\n", program);
		logerror("argc was %d", argc);
		exit(1);
	}
	time(&now);
	srandom(now);
	produce = 0;
	if (strcmp(argv[1], "produce") == 0)
		produce = 1;
	else if (strcmp(argv[1], "mob") != 0) {
		logerror("no such update type %s\n", argv[1]);
		exit(1);
	}
	if ((etu = atoi(argv[2])) <= 0) {
		logerror("etu value must be positive\n");
		exit(1);
	}
	if (etu != etu_per_update) {
		logerror("warning: etu_per_update: %d, argv[2]: %d",
			etu_per_update, etu);
	}
	errno = 0;
	logerror("%s update pid %d", argv[1], getpid());
	io_init();
	if (!tm_connect()) {
		logerror("can't connect to transaction manager");
		exit(1);
	}
	ef_open(EF_NATION, O_RDONLY, EFF_MEM);
	ef_open(EF_SECTOR, O_RDWR, EFF_MEM);
	ef_open(EF_SHIP, O_RDWR, EFF_MEM);
	ef_open(EF_PLANE, O_RDWR, EFF_MEM);
	if (produce) {
		/*
		 * set up all the variables which get used in the
		 * sector production routine (for producing education,
		 * happiness, and printing out the state of the nation)
		 */
		logerror("production update (%d etus)", etu);
		ef_open(EF_NEWS, O_RDWR, 0);
		bzero((char *)pops, sizeof(pops));
		bzero((char *)air_money, sizeof(air_money));
		bzero((char *)sea_money, sizeof(sea_money));
		for (n=0; n<MAXNOC; n++) {
			money[n] = 0;
			if ((np = getnatp(n)) == 0)
				continue;
			money[n] = np->nat_money;
		}
#ifndef BUDGET
		prod_ship(etu);
		prod_plane(etu);
		/*
		 * NOTE: prod_sect MUST be last after all other production
		 * in order to have a proper tally of the pop and money
		 * used this update
		 */
		prod_sect(etu);
#else
		prepare_sects(etu);
		for(x=0;x<MAXNOC;x++){
			int	y,z,sb=0,sm=0,pb=0,pm=0;
			struct natstr *np;

			np=getnatp(x);
			np->nat_money += (int) (np->nat_reserve * money_res);
			for(y=1;y<SCT_MAXDEF+6;y++){
				for(z=0;z<SCT_MAXDEF+6;z++)
					if (np->nat_priorities[z] == y)
						do_prod(z,etu,x,
							&sb,&sm,&pb,&pm);
			}
			/* 0 is maintain, 1 is build */
			if (!sm) prod_ship(etu,x,0);
			if (!sb) prod_ship(etu,x,1);
			if (!pm) prod_plane(etu,x,0);
			if (!pb) prod_plane(etu,x,1);
			/* produce all sects that haven't produced yet */
			produce_sect(x,etu,-1);
		}
		finish_sects(etu);
#endif /* BUDGET */
		prod_nat(etu);
		age_levels(etu);
		ef_close(EF_NEWS);
		flushwu();
#ifdef SLOW_WAR
		/* Update war declarations */
		/* MOBILIZATION->SITZKRIEG->AT_WAR */
		for (cn=1; cn < MAXNOC; cn++){
			if ((cnp = getnatp(cn)) == 0)
				break;
			for (cn2=1; cn2 < MAXNOC; cn2++) {
				if (cn2 == cn)
                        		continue;
				rel=getrel(cnp,cn2);
				if (rel == MOBILIZATION){
				    rel = SITZKRIEG;
				    setrel(cn,cn2,rel);
				}
				else if (rel == SITZKRIEG){
				    rel = AT_WAR;
				    setrel(cn,cn2,rel);
			    	}
			}
        	}
#endif /* SLOW_WAR */
	}
	mob_ship(etu);
	mob_sect(etu);
	mob_plane(etu);
#ifdef DEMANDUPDATE
	update_removewants();
#endif DEMANDUPDATE
	ef_close(EF_SECTOR);
	ef_close(EF_SHIP);
	ef_close(EF_PLANE);
	logerror("End %s update", argv[1]);
	tm_exit(0);
	ef_close(EF_NATION);
}

tm_exit(code)
	int	code;
{
	extern	iop_t iop;
	struct	timeval tv;

	tm_close();
	io_noblocking(iop, 1);
	while (!io_eof(iop) && !io_error(iop)){
		io_flush();
		io_select(0);
		io_input(iop);
		io_output(iop);
	}

	io_close(iop);
	logerror("exiting");
	exit(code);
}

#ifdef BUDGET
do_prod(sector_type,etu,n,ship_build,ship_maint,plane_build,plane_maint)
	int sector_type;
	int n,*ship_build,*ship_maint;
	int *plane_build,*plane_maint;
{
	if (sector_type == PRI_SMAINT){
		prod_ship(etu,n,0);
		*ship_maint=1;
	}
	else
	if (sector_type == PRI_SBUILD){
		prod_ship(etu,n,1);
		*ship_build=1;
	}
	else
	if (sector_type == PRI_PMAINT){
		prod_plane(etu,n,0);
		*plane_build=1;
	}
	else
	if (sector_type == PRI_PBUILD){
		prod_plane(etu,n,1);
		*plane_build=1;
	}
	else
		produce_sect(n,etu,sector_type);
}
#endif /* BUDGET */
