// File: roberty65[P]bServer/serverd/src/main.cpp
// Function: main
int main(int argc, char **argv)
{
	const char *etcFile = "../conf/server.conf";
	int daemonMode = 1;
	int ch, showVersion = 0;

	while ((ch = getopt(argc, argv, "dc:hv")) != EOF) {
		switch (ch) {
		case 'd':
			daemonMode = 0;
			break;
		case 'c':
			etcFile = optarg;
			break;
		case 'v':
			showVersion = 1;
			break;
		case 'h':
			usage(argv[0]);
			exit(0);
		default:
			fprintf(stderr, "invalid argument: %c\n", ch);
			usage(argv[0]);
			exit(1);
		}	
	}

	if (loadConfig(etcFile) < 0) {
		fprintf(stderr, "load config from %s failed: %m\n", etcFile);
		exit(1);
	}

	if (daemonMode) {
		int retval = daemon(1, 1);
		assert(retval == 0);

		if (fork() != 0) exit(0); // exit if not child
		setsid();

		struct sigaction act;
		act.sa_flags = 0;
		act.sa_handler = sigExit;
		sigaction(SIGTERM, &act, NULL);
		sigaction(SIGINT, &act, NULL);

		signal(SIGHUP, SIG_IGN);
		signal(SIGQUIT, SIG_IGN);
		signal(SIGPIPE, SIG_IGN);
		signal(SIGCHLD, SIG_IGN);
		signal(SIGTSTP, SIG_IGN);
		signal(SIGTTIN, SIG_IGN);
		signal(SIGTTOU, SIG_IGN);

		// TODO: mask other signal???

		// fork again?
		//setpgrp();
	}

	if (showVersion) {
		//Processor *processor = loadProcessor(businessProcessor);
		// TODO:
		exit(0);
	}

	if (BPROF_INIT(items, sizeof(items)/sizeof(items[0])-1) < 0) {
		fprintf(stderr, "bprof-init failed: %m\n");
		exit(1);
	}

	SYSLOG_INIT(logFileName, logLevel, logFileMaxSize, logMaxBackup);
	if (sysLogHandle == NULL) {
		fprintf(stderr, "SYS-LOG-INIT failed: %m\n");
		exit(1);
	}
	else {
		SYSLOG_INFO("serverd started");
	}
	
	Queue<Message> *inQ = new Queue<Message>(systemInQueueSize);
	Queue<Message> *outQ = new Queue<Message>(systemOutQueueSize);

	Processor *processor = loadProcessor(businessProcessor);
	processor->setSendFunc(async_send_delegator, outQ);

	EventManager *emgr = new EventManager(outQ, 1024);
	emgr->setMessageExpire(systemInMessageExpire, systemOutMessageExpire);

	emgr->setConnectionMaxIdle(connectionIdleTimeout);
	emgr->setConnectionOutQueueSize(connectionOutQueueSize);

	emgr->setHelloInterval(connectorHelloInterval);
	emgr->setReconnectDelay(reconnectDelay);

	int retval = emgr->addListener(listenAddress, inQ, processor, listenMaxConnection);
	if (retval < 0) {
		SYSLOG_FATAL("addListener at %s failed", listenAddress);
		return 1;
	}

	if (!connectors.empty()) for (ConnectorMap::iterator iter = connectors.begin(); iter != connectors.end(); ++iter) {
		int cid = emgr->addConnector(iter->second.address, inQ, processor, 1);
		if (cid < 0) {
			SYSLOG_FATAL("addConnector(%s) failed", iter->first.c_str());
			return 2;
		}
	
		iter->second.flow = cid;
		SYSLOG_DEBUG("connector=%s, flow=%d", iter->first.c_str(), cid);
	}

	// init here for it may call add/getConnector
	if (processor->onInit() < 0) {
		SYSLOG_FATAL("processor onInit failed: %m");
		exit(1);
	}

	// start worker before event manager starts
	MtWorker *mtWorker = new MtWorker(inQ, processor, systemThreadCount);
	mtWorker->start();

	emgr->start();

	// nothing
	processor->onExit();
	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x170, %rsp            # imm = 0x170
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
leaq 0xe657(%rip), %rax      # 0x12167
movq %rax, -0x18(%rbp)
movl $0x1, -0x1c(%rbp)
movl $0x0, -0x24(%rbp)
movl -0x8(%rbp), %edi
movq -0x10(%rbp), %rsi
leaq 0xe64b(%rip), %rdx      # 0x1217b
callq 0x30b0
movl %eax, -0x20(%rbp)
cmpl $-0x1, %eax
je 0x3bd7
movl -0x20(%rbp), %eax
addl $-0x63, %eax
movl %eax, %ecx
movq %rcx, -0x120(%rbp)
subl $0x13, %eax
ja 0x3ba1
movq -0x120(%rbp), %rax
leaq 0xe4a1(%rip), %rcx      # 0x12004
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl $0x0, -0x1c(%rbp)
jmp 0x3bd2
movq 0x16444(%rip), %rax     # 0x19fc0
movq (%rax), %rax
movq %rax, -0x18(%rbp)
jmp 0x3bd2
movl $0x1, -0x24(%rbp)
jmp 0x3bd2
movq -0x10(%rbp), %rax
movq (%rax), %rdi
callq 0x42d0
xorl %edi, %edi
callq 0x34e0
movq 0x16430(%rip), %rax     # 0x19fd8
movq (%rax), %rdi
movl -0x20(%rbp), %edx
leaq 0xe5cc(%rip), %rsi      # 0x12181
movb $0x0, %al
callq 0x35a0
movq -0x10(%rbp), %rax
movq (%rax), %rdi
callq 0x42d0
movl $0x1, %edi
callq 0x34e0
jmp 0x3b22
movq -0x18(%rbp), %rdi
callq 0x4300
cmpl $0x0, %eax
jge 0x3c0b
movq 0x163ec(%rip), %rax     # 0x19fd8
movq (%rax), %rdi
movq -0x18(%rbp), %rdx
leaq 0xe59d(%rip), %rsi      # 0x12197
movb $0x0, %al
callq 0x35a0
movl $0x1, %edi
callq 0x34e0
cmpl $0x0, -0x1c(%rbp)
je 0x3d09
movl $0x1, %esi
movl %esi, %edi
callq 0x34c0
movl %eax, -0x28(%rbp)
cmpl $0x0, -0x28(%rbp)
jne 0x3c2c
jmp 0x3c4b
leaq 0xe584(%rip), %rdi      # 0x121b7
leaq 0xe589(%rip), %rsi      # 0x121c3
movl $0xd3, %edx
leaq 0xe586(%rip), %rcx      # 0x121cc
callq 0x3250
callq 0x30d0
cmpl $0x0, %eax
je 0x3c5c
xorl %edi, %edi
callq 0x34e0
callq 0x3450
movl $0x0, -0x38(%rbp)
leaq 0xcf1(%rip), %rax       # 0x4960
movq %rax, -0xc0(%rbp)
movl $0xf, %edi
leaq -0xc0(%rbp), %rsi
xorl %eax, %eax
movl %eax, %edx
callq 0x3500
movl $0x2, %edi
leaq -0xc0(%rbp), %rsi
xorl %eax, %eax
movl %eax, %edx
callq 0x3500
movl $0x1, %edi
movl $0x1, %esi
callq 0x34b0
movl $0x3, %edi
movl $0x1, %esi
callq 0x34b0
movl $0xd, %edi
movl $0x1, %esi
callq 0x34b0
movl $0x11, %edi
movl $0x1, %esi
callq 0x34b0
movl $0x14, %edi
movl $0x1, %esi
callq 0x34b0
movl $0x15, %edi
movl $0x1, %esi
callq 0x34b0
movl $0x16, %edi
movl $0x1, %esi
callq 0x34b0
cmpl $0x0, -0x24(%rbp)
je 0x3d16
xorl %edi, %edi
callq 0x34e0
jmp 0x3d18
movl $0x218, %edi            # imm = 0x218
callq 0x33c0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x128(%rbp)
movq 0x167da(%rip), %rsi     # 0x1a510
movl 0x167dc(%rip), %edx     # 0x1a518
movq 0x167dd(%rip), %rcx     # 0x1a520
movq 0x167de(%rip), %r8      # 0x1a528
callq 0xbed0
jmp 0x3d51
movq -0x128(%rbp), %rcx
leaq 0x16889(%rip), %rax     # 0x1a5e8
movq %rcx, (%rax)
leaq 0x1687f(%rip), %rax     # 0x1a5e8
cmpq $0x0, (%rax)
jne 0x3db9
movq 0x16262(%rip), %rax     # 0x19fd8
movq (%rax), %rdi
leaq 0xe463(%rip), %rsi      # 0x121e3
movb $0x0, %al
callq 0x35a0
movl $0x1, %edi
callq 0x34e0
movq -0x128(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
movl $0x218, %esi            # imm = 0x218
callq 0x33d0
jmp 0x42c3
jmp 0x3dbb
leaq 0x16826(%rip), %rax     # 0x1a5e8
movq (%rax), %rdi
movl $0x4, %esi
callq 0x4b50
cmpl $0x0, %eax
je 0x3df1
leaq 0x1680d(%rip), %rax     # 0x1a5e8
movq (%rax), %rdi
movl $0x4, %esi
leaq 0xe412(%rip), %rdx      # 0x121fc
movb $0x0, %al
callq 0xbf40
jmp 0x3df3
jmp 0x3df5
movl $0xb0, %edi
callq 0x33c0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x130(%rbp)
movslq 0x1671d(%rip), %rsi     # 0x1a530
callq 0x4b80
jmp 0x3e1a
movq -0x130(%rbp), %rax
movq %rax, -0xd8(%rbp)
movl $0xb0, %edi
callq 0x33c0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x138(%rbp)
movslq 0x166ee(%rip), %rsi     # 0x1a534
callq 0x4b80
jmp 0x3e4d
movq -0x138(%rbp), %rax
movq %rax, -0xe0(%rbp)
movq 0x16776(%rip), %rdi     # 0x1a5d8
callq 0x3970
movq %rax, -0xe8(%rbp)
movq -0xe8(%rbp), %rdi
movq -0xe0(%rbp), %rdx
leaq 0x4eed(%rip), %rsi      # 0x8d70
callq 0x4be0
movl $0x70, %edi
callq 0x33c0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x140(%rbp)
movq -0xe0(%rbp), %rsi
movl $0x400, %edx            # imm = 0x400
callq 0x72a0
jmp 0x3eb2
movq -0x140(%rbp), %rax
movq %rax, -0xf0(%rbp)
movq -0xf0(%rbp), %rdi
movl 0x1666b(%rip), %esi     # 0x1a538
movl 0x16669(%rip), %edx     # 0x1a53c
callq 0x4c10
movq -0xf0(%rbp), %rdi
movl 0x1665b(%rip), %esi     # 0x1a540
callq 0x4c40
movq -0xf0(%rbp), %rdi
movl 0x1664d(%rip), %esi     # 0x1a544
callq 0x4c60
movq -0xf0(%rbp), %rdi
movl 0x1663f(%rip), %esi     # 0x1a548
callq 0x4c80
movq -0xf0(%rbp), %rdi
movl 0x16631(%rip), %esi     # 0x1a54c
callq 0x4ca0
movq -0xf0(%rbp), %rdi
movq 0x166b2(%rip), %rsi     # 0x1a5e0
movq -0xd8(%rbp), %rdx
movq -0xe8(%rbp), %rcx
movl 0x1660d(%rip), %r8d     # 0x1a550
callq 0x7590
movl %eax, -0xf4(%rbp)
cmpl $0x0, -0xf4(%rbp)
jge 0x4026
jmp 0x3f5d
leaq 0x16684(%rip), %rax     # 0x1a5e8
movq (%rax), %rdi
movl $0x1, %esi
callq 0x4b50
cmpl $0x0, %eax
je 0x4018
leaq 0x16667(%rip), %rax     # 0x1a5e8
movq (%rax), %rdi
movq 0x16655(%rip), %rcx     # 0x1a5e0
movl $0x1, %esi
leaq 0xe275(%rip), %rdx      # 0x1220c
movb $0x0, %al
callq 0xbf40
jmp 0x4018
movq -0x130(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
movl $0xb0, %esi
callq 0x33d0
jmp 0x42c3
movq -0x138(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
movl $0xb0, %esi
callq 0x33d0
jmp 0x42c3
movq -0x140(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
movl $0x70, %esi
callq 0x33d0
jmp 0x42c3
jmp 0x401a
movl $0x1, -0x4(%rbp)
jmp 0x42b7
leaq 0x1657b(%rip), %rdi     # 0x1a5a8
callq 0x4cc0
testb $0x1, %al
jne 0x41ce
leaq 0x16567(%rip), %rdi     # 0x1a5a8
callq 0x4ce0
movq %rax, -0x100(%rbp)
leaq 0x16554(%rip), %rdi     # 0x1a5a8
callq 0x4b00
movq %rax, -0x108(%rbp)
leaq -0x100(%rbp), %rdi
leaq -0x108(%rbp), %rsi
callq 0x4d10
testb $0x1, %al
jne 0x407c
jmp 0x41cc
movq -0xf0(%rbp), %rax
movq %rax, -0x148(%rbp)
leaq -0x100(%rbp), %rdi
callq 0x4b30
movq -0x148(%rbp), %rdi
movq 0x20(%rax), %rsi
movq -0xd8(%rbp), %rdx
movq -0xe8(%rbp), %rcx
movl $0x1, %r8d
callq 0x77e0
movl %eax, -0x10c(%rbp)
cmpl $0x0, -0x10c(%rbp)
jge 0x4134
jmp 0x40cb
leaq 0x16516(%rip), %rax     # 0x1a5e8
movq (%rax), %rdi
movl $0x1, %esi
callq 0x4b50
cmpl $0x0, %eax
je 0x4126
leaq 0x164fd(%rip), %rax     # 0x1a5e8
movq (%rax), %rax
movq %rax, -0x150(%rbp)
leaq -0x100(%rbp), %rdi
callq 0x4b30
movq %rax, %rdi
callq 0x3150
movq -0x150(%rbp), %rdi
movq %rax, %rcx
movl $0x1, %esi
leaq 0xe106(%rip), %rdx      # 0x12225
movb $0x0, %al
callq 0xbf40
jmp 0x4128
movl $0x2, -0x4(%rbp)
jmp 0x42b7
movl -0x10c(%rbp), %eax
movl %eax, -0x154(%rbp)
leaq -0x100(%rbp), %rdi
callq 0x4b30
movl -0x154(%rbp), %ecx
movl %ecx, 0x28(%rax)
leaq 0x1648c(%rip), %rax     # 0x1a5e8
movq (%rax), %rdi
movl $0x5, %esi
callq 0x4b50
cmpl $0x0, %eax
je 0x41b7
leaq 0x16473(%rip), %rax     # 0x1a5e8
movq (%rax), %rax
movq %rax, -0x160(%rbp)
leaq -0x100(%rbp), %rdi
callq 0x4b30
movq %rax, %rdi
callq 0x3150
movq -0x160(%rbp), %rdi
movq %rax, %rcx
movl -0x10c(%rbp), %r8d
movl $0x5, %esi
leaq 0xe08d(%rip), %rdx      # 0x1223d
movb $0x0, %al
callq 0xbf40
jmp 0x41b9
jmp 0x41bb
leaq -0x100(%rbp), %rdi
callq 0x4d40
jmp 0x404d
jmp 0x41ce
movq -0xe8(%rbp), %rdi
movq (%rdi), %rax
callq *0x20(%rax)
cmpl $0x0, %eax
jge 0x4224
jmp 0x41e2
leaq 0x163ff(%rip), %rax     # 0x1a5e8
movq (%rax), %rdi
movl $0x1, %esi
callq 0x4b50
cmpl $0x0, %eax
je 0x4218
leaq 0x163e6(%rip), %rax     # 0x1a5e8
movq (%rax), %rdi
movl $0x1, %esi
leaq 0xe042(%rip), %rdx      # 0x12253
movb $0x0, %al
callq 0xbf40
jmp 0x421a
movl $0x1, %edi
callq 0x34e0
movl $0x20, %edi
callq 0x33c0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x168(%rbp)
movq -0xd8(%rbp), %rsi
movq -0xe8(%rbp), %rdx
movl 0x16305(%rip), %ecx     # 0x1a554
callq 0x8a40
jmp 0x4256
movq -0x168(%rbp), %rax
movq %rax, -0x118(%rbp)
movq -0x118(%rbp), %rdi
callq 0x8c80
movq -0xf0(%rbp), %rdi
callq 0x8610
movq -0xe8(%rbp), %rdi
movq (%rdi), %rax
callq *0x28(%rax)
movl $0x0, -0x4(%rbp)
jmp 0x42b7
movq -0x168(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
movl $0x20, %esi
callq 0x33d0
jmp 0x42c3
movl -0x4(%rbp), %eax
addq $0x170, %rsp            # imm = 0x170
popq %rbp
retq
movq -0xc8(%rbp), %rdi
callq 0x3690
nop