/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/***************************************************************************
 *            pracrod.cc
 *
 *  Wed Aug 22 12:15:59 CEST 2007
 *  Copyright 2007 Bent Bisballe Nyeng
 *  deva@aasimon.org
 ****************************************************************************/

/*
 *  This file is part of Pracro.
 *
 *  Pracro 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.
 *
 *  Pracro 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 Pracro; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
 */
// For ETC
#include <config.h>

#include "daemon.h"

// For setuid and setgid
#include <sys/types.h>
#include <unistd.h>

// For signal
#include <signal.h>

// For errno and strerror
#include <errno.h>

#include <stdio.h>

#include <stdlib.h>
#include <string.h>

// For getpwent and getgrent
#include <sys/types.h>
#include <grp.h>
#include <pwd.h>

// For getopt_long and friends
#include <getopt.h>

#include "configuration.h"

#include "server.h"

#include "tcpsocket.h"

static const char version_str[] =
"Pracro server v" VERSION "\n"
;

static const char copyright_str[] =
"Copyright (C) 2006-2007 Bent Bisballe Nyeng - Aasimon.org.\n"
"This is free software.  You may redistribute copies of it under the terms of\n"
"the GNU General Public License <http://www.gnu.org/licenses/gpl.html>.\n"
"There is NO WARRANTY, to the extent permitted by law.\n"
"\n"
"Written by Bent Bisballe Nyeng (deva@aasimon.org)\n"
;

static const char usage_str[] =
"Usage: %s [options]\n"
"Options:\n"
"  -c, --config file   Read configfile from 'file'\n"
"  -f, --foreground    Run in foreground mode (non-background mode)\n"
"  -u, --user user     Run as 'user' (overrides the configfile)\n"
"  -g, --group group   Run as 'group' (overrides the configfile)\n"
"  -v, --version       Print version information and exit.\n"
"  -h, --help          Print this message and exit.\n"
;

void reload(int fisk)
{
  int port;
  printf("Reload!\n");
  port = config()->lookup("port");
  config()->reload();

  { // Force wake the server process for reinitialization.
    TCPSocket socket;
    socket.connect("localhost", port);
  }
}

class PracroDaemon : public Daemon {
private:
  int daemon_main();
};

int PracroDaemon::daemon_main()
{
  // Activate the server main loop.
  server();

  return 0;
}

int main(int argc, char *argv[])
{
  int c;
  char *configfile = NULL;
  char *user = NULL;
  char *group = NULL;
  bool foreground = false;

  int option_index = 0;
  while(1) {
    //    int this_option_optind = optind ? optind : 1;
    static struct option long_options[] = {
      {"foreground", no_argument, 0, 'f'},
      {"config", required_argument, 0, 'c'},
      {"user", required_argument, 0, 'u'},
      {"group", required_argument, 0, 'g'},
      {"help", no_argument, 0, 'h'},
      {"version", no_argument, 0, 'v'},
      {0, 0, 0, 0}
    };
    
    c = getopt_long (argc, argv, "hvfc:u:g:", long_options, &option_index);
    
    if (c == -1)
      break;

    switch(c) {
    case 'c':
      configfile = strdup(optarg);
      break;

    case 'f':
      foreground = true;
      break;

    case 'u':
      user = strdup(optarg);
      break;

    case 'g':
      group = strdup(optarg);
      break;

    case '?':
    case 'h':
      printf(version_str);
      printf(usage_str, argv[0]);
      return 0;

    case 'v':
      printf(version_str);
      printf(copyright_str);
      return 0;

    default:
      break;
    }
  }

  char defval[512];
  sprintf(defval, ETC"/pracrod.conf");

  char *cfname = NULL;
  if(!configfile) cfname = defval;//ETC"/pracrod.conf";
  else cfname = configfile;
  Configuration conf(cfname);
  initConfig(&conf);

  if(!user) {
    std::string userstr;
    try {
      user = (char*)(const char*)config()->lookup("user");
    } catch( ... ) {
      printf("User not found in config.\n");
    }
  }


  if(!group) {
    std::string groupstr;
    try {
      group = (char*)(const char*)config()->lookup("group");
    } catch( ... ) {
      printf("Group not found in config.\n");
    }

  }

  PracroDaemon daemon;
  daemon.run(user, group, !foreground);

  // Clean up
  if(configfile) free(configfile);
  if(user) free(user);
  if(group) free(group);

  return 0;
}