/*
 * Copyright (C) 2015 by the University of Southern California
 * $Id: main.cc 24208 2015-05-28 01:07:42Z liangzhu $
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * 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.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 *
 */

#include <iostream>
#include <string>
#include <algorithm>
#include <unistd.h>
#include "global_var.h"
#include "client_proxy.hh"
using namespace std;

int log_level = LOG_DEBUG;
void usage(const char *comm) {
  cerr << " Usage:\n " << comm << "[-alpsth]\n"
    " -a IP            listening address, default is 127.0.0.1\n"
    " -l PORT          listening port, default is port 53\n"
    " -p SERV_PORT     server port, default is 53\n"
    " -s SERV_IP       server ip address\n"
    " -t CONNECTION    upstream over TCP/STARTTLS/SSL\n"
    "                  default STARTTLS\n"
    " -h               print this help message\n";
  exit(1);
}

void str_upper(string &s)
{
  for (unsigned int i=0; i<s.length(); i++)
    s[i] = toupper(s[i]);
}

int main(int argc, char *argv[])
{
  const char *comm = argv[0];
  if (argc == 1) usage(comm);
  
  string svr_ip, lis_ip = "127.0.0.1", conn;
  int svr_port = 53, lis_port = 53, conn_type = CONN_TCP;
  int opt = -1;
  while ((opt = getopt(argc, argv, "a:l:p:s:t:h")) != -1) {
    switch(opt) {
    case 'a':
      lis_ip = optarg;
      break;
    case 'l':
      lis_port = atoi(optarg);
      break;
    case 'p':
      svr_port = atoi(optarg);
      break;
    case 's':
      svr_ip = optarg;
      break;
    case 't':
      conn = optarg;
      break;
    default:
      usage(comm);
    }
  }

  if (svr_ip.length() == 0)
    errx(1, "[error] server ip must be not given, abort!");

  if (svr_port <= 0) {
    warnx("[warn] use default server port 53!");
    svr_port = 53;
  }

  if (conn.length() == 0) {
    warnx("[warn] connection type is not given, use default STARTTLS");
    conn = "STARTTLS";
  }

  str_upper(conn);
  
  if (conn == "TCP") {
    DBG("start proxy as TCP\n");
    conn_type = CONN_TCP;
  } else if (conn == "SSL" || conn == "TLS") {
    DBG("start proxy as direct SSL\n");
    conn_type = CONN_SSL;
  } else if (conn == "STARTTLS" || conn == "STARTSSL") {
    DBG("start proxy as STARTTLS\n");
    conn_type = CONN_STARTTLS;
  } else
    errx(1, "[error] unknow connection type[%s]", conn.c_str());

  if (lis_port <= 0) {
    lis_port = 53;
    warnx("[warn] upstream %s: use default port 53!", conn.c_str());
  }

  DBG("upstream [%s]: listen ip [%s], port [%d]\n", conn.c_str(), lis_ip.c_str(), lis_port);
  DBG("server ip [%s], port [%d]\n", svr_ip.c_str(), svr_port);
  client_proxy clt_pxy(svr_ip.c_str(), svr_port, 
		       lis_ip.c_str(), lis_port, conn_type);
  clt_pxy.start();
  DBG("ends\n");
  return 0;
}
