#!/usr/bin/env python
# Copyright (C) 2013  Lukas Rist <glaslos@gmail.com>
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

import logging
import os
import argparse
import sys
from ConfigParser import ConfigParser

import gevent
from gevent.queue import Queue

import conpot
from conpot.logging.log_worker import LogWorker
from conpot.snmp.snmp_server import SNMPServer
from conpot.modbus.modbus_server import ModbusServer
from conpot.hmi.web_server import HTTPServer

logger = logging.getLogger()
package_directory = os.path.dirname(os.path.abspath(conpot.__file__))


def logo():
    print """
                       _
   ___ ___ ___ ___ ___| |_
  |  _| . |   | . | . |  _|
  |___|___|_|_|  _|___|_|
              |_|

  Version {0}
  Glastopf Project
""".format(conpot.__version__)


def setup_logging():
    root_logger = logging.getLogger()

    console_log = logging.StreamHandler()
    console_log.setLevel(logging.DEBUG)
    console_log.setFormatter(logging.Formatter('%(asctime)-15s %(message)s'))
    root_logger.addHandler(console_log)
    logger.setLevel(logging.DEBUG)


def main():
    logo()
    setup_logging()

    parser = argparse.ArgumentParser()

    parser.add_argument("-w", "--www",
                        help="public www path",
                        default=os.path.join(package_directory, 'www/'),
                        metavar="www/"
                        )
    parser.add_argument("-r", "--www-root",
                        help="www root page",
                        default="index.htm",
                        metavar="page.htm"
                        )
    parser.add_argument("-t", "--template",
                        help="the template to use",
                        default=os.path.join(package_directory, 'templates/default.xml'),
                        metavar="template.xml"
                        )
    parser.add_argument("-c", "--config",
                        help="the configuration file to use",
                        default=os.path.join(package_directory, 'conpot.cfg'),
                        metavar="config.cfg"
                        )
    parser.add_argument("-m", "--mibpath",
                        help="path to compiled MIB files. (compiled with build-pysnmp-mib)",
                        default=os.getcwd())
    args = parser.parse_args()

    config = ConfigParser()
    if not os.path.isfile(args.config):
        args.config = os.path.join(package_directory, 'conpot.cfg')
        logger.info('No conpot.cfg found in current directory, using default configuration: {0}'.format(args.config))
    config.read(args.config)

    if not os.path.isfile(args.template):
        logger.error('Template not found: {0}'.format(args.template))
        sys.exit(1)
    if not os.path.isfile(args.config):
        logger.error('Config not found: {0}'.format(args.config))
        sys.exit(1)

    logger.info('Starting Conpot using template found in: {0}'.format(args.template))
    logger.info('Starting Conpot using configuration found in: {0}'.format(args.config))
    logger.info('Starting Conpot using www templates found in: {0}'.format(args.www))

    log_queue = Queue()
    log_worker = LogWorker(config, log_queue)
    gevent.spawn(log_worker.start)

    modbus_host = config.get('modbus', 'host')
    modbus_port = config.getint('modbus', 'port')
    m = ModbusServer(args.template, log_queue)
    modbus_server = m.get_server(modbus_host, modbus_port)

    snmp_host = config.get('snmp', 'host')
    snmp_port = config.getint('snmp', 'port')
    snmp_server = SNMPServer(snmp_host, snmp_port, args.template, log_queue, args.mibpath)

    http_host = config.get('http', 'host')
    http_port = config.getint('http', 'port')
    http_server = HTTPServer(log_queue, args, http_host, http_port, snmp_port)

    servers = list()
    try:
        servers.append(gevent.spawn(modbus_server.serve_forever))
        servers.append(gevent.spawn(snmp_server.start))
        servers.append(gevent.spawn(http_server.run))
        gevent.joinall(servers)
    except KeyboardInterrupt:
        logging.info('Stopping Conpot')
        log_worker.stop()
        snmp_server.stop()
        modbus_server.stop()

    #just being nice and cosy!
    gevent.joinall(servers, 2)



if __name__ == "__main__":
    main()
