#!/usr/bin/env python
import sys
from codecs import getwriter
from os import getenv
from signal import SIGINT, signal
from sys import stderr, stdout

import main
import modules.counters
from api.views import API
from core.relay import RelayFactory
from core.server import ServerFactory
from twisted.internet import reactor

# Webapp stuff
from twisted.internet.protocol import Factory
from twisted.internet.ssl import DefaultOpenSSLContextFactory
from utils.cleanup import handler
from utils.loaders.command_loader import loadCommands
from utils.logging.log import log

Factory.noisy = False

main.initMain()

if "--debug" in sys.argv:  # yes really
    main.config["Debug"] = True
if "--trace" in sys.argv:
    main.config["Trace"] = True
if "--migrate" in sys.argv:
    from modules.network import migrate

    migrate()
    exit()
loadCommands()


# core.logstash.init_logstash()
signal(SIGINT, handler)  # Handle Ctrl-C and run the cleanup routine
stdout = getwriter("utf8")(stdout)  # this is a generic fix but we all know
stderr = getwriter("utf8")(stderr)  # it's just for the retards on Rizon using
#  unicode quit messages for no reason

trues = ("true", "1", "t", True)

# Main listener
listener_address = getenv("THRESHOLD_LISTENER_HOST", main.config["Listener"]["Address"])
listener_port = int(getenv("THRESHOLD_LISTENER_PORT", main.config["Listener"]["Port"]))
listener_ssl = (
    getenv("THRESHOLD_LISTENER_SSL", main.config["Listener"]["UseSSL"]) in trues
)

# RelayAPI
relay_enabled = (
    getenv("THRESHOLD_RELAY_ENABLED", main.config["RelayAPI"]["Enabled"]) in trues
)
relay_address = getenv("THRESHOLD_RELAY_HOST", main.config["RelayAPI"]["Address"])
relay_port = int(getenv("THRESHOLD_RELAY_PORT", main.config["RelayAPI"]["Port"]))
relay_ssl = getenv("THRESHOLD_RELAY_SSL", main.config["RelayAPI"]["UseSSL"]) in trues

# Web API
api_enabled = getenv("THRESHOLD_API_ENABLED", main.config["API"]["Enabled"]) in trues
api_address = getenv("THRESHOLD_API_HOST", main.config["API"]["Address"])
api_port = int(getenv("THRESHOLD_API_PORT", main.config["API"]["Port"]))

# Debugging
debug_enabled = getenv("THRESHOLD_DEBUG", main.config["Debug"]) in trues
trace_enabled = getenv("THRESHOLD_TRACE", main.config["Trace"]) in trues
if debug_enabled:
    main.config["Debug"] = True
if trace_enabled:
    main.config["Trace"] = True


if __name__ == "__main__":
    listener = ServerFactory()
    if listener_ssl is True:
        reactor.listenSSL(
            listener_port,
            listener,
            DefaultOpenSSLContextFactory(
                main.certPath + main.config["Key"],
                main.certPath + main.config["Certificate"],
            ),
            interface=listener_address,
        )
        log("Threshold running with SSL on %s:%s" % (listener_address, listener_port))
    else:
        reactor.listenTCP(
            listener_port,
            listener,
            interface=listener_address,
        )
        log("Threshold running on %s:%s" % (listener_address, listener_port))
    if relay_enabled:
        relay = RelayFactory()
        if relay_ssl is True:
            reactor.listenSSL(
                relay_port,
                relay,
                DefaultOpenSSLContextFactory(
                    main.certPath + main.config["Key"],
                    main.certPath + main.config["Certificate"],
                ),
                interface=relay_address,
            )
            log(
                "Threshold relay running with SSL on %s:%s"
                % (relay_address, relay_port)
            )
        else:
            reactor.listenTCP(
                relay_port,
                relay,
                interface=relay_address,
            )
            log("Threshold relay running on %s:%s" % (relay_address, relay_port))
    for net in main.network.keys():
        main.network[net].start_bots()
    modules.counters.setupCounterLoop()
    if api_enabled:
        api = API()
        api.app.run(api_address, api_port)
    else:
        reactor.run()
