"""
Simple Datadog HTTP logger.
"""

from __future__ import absolute_import

from io import BytesIO
from json import dumps
from platform import node

from core import output
from core.config import CONFIG
from core.tools import to_bytes

from twisted.internet import reactor
from twisted.python.log import msg
from twisted.web import client, http_headers
from twisted.web.client import FileBodyProducer
from twisted.internet.ssl import ClientContextFactory


class WebClientContextFactory(ClientContextFactory):
    def getContext(self, hostname, port):
        return ClientContextFactory.getContext(self)


class QuietHTTP11ClientFactory(client._HTTP11ClientFactory):
    noisy = False


class Output(output.Output):
    def start(self):
        self.url = CONFIG.get('output_datadog', 'url')
        self.api_key = CONFIG.get('output_datadog', 'api_key', fallback='')
        if len(self.api_key) == 0:
            msg('output_datadog: API key is not defined.')
        self.ddsource = CONFIG.get('output_datadog', 'ddsource', fallback='siphoney')
        self.ddtags = CONFIG.get('output_datadog', 'ddtags', fallback='env:dev')
        self.service = CONFIG.get('output_datadog', 'service', fallback='honeypot')
        self.hostname = CONFIG.get('output_datadog', 'hostname', fallback=node())

        contextFactory = WebClientContextFactory()
        myQuietPool = client.HTTPConnectionPool(reactor)
        myQuietPool._factory = QuietHTTP11ClientFactory
        self.agent = client.Agent(reactor, contextFactory=contextFactory, pool=myQuietPool)

    def stop(self):
        pass

    def write(self, event):
        messg = '{} INFO [SIP Honey on {}]: {} from {}:{}.'.format(
            event['timestamp'], event['sensor'],
            event['message'], event['src_ip'], event['dst_port']
        )
        event['message'] = messg
        event['ddsource'] = self.ddsource
        event['ddtags'] = self.ddtags
        event['hostname'] = self.hostname
        event['service'] = self.service
        self.postentry(event)

    def postentry(self, entry):
        base_headers = {
            b'Accept': [b'application/json'],
            b'Content-Type': [b'application/json'],
            b'DD-API-KEY': [to_bytes(self.api_key)],
        }
        headers = http_headers.Headers(base_headers)
        body = FileBodyProducer(BytesIO(to_bytes(dumps(entry, sort_keys=True))))
        self.agent.request(b'POST', to_bytes(self.url), headers, body)

