#!/usr/bin/env python

import os
import sys

sys.path.append(os.path.abspath(
    os.path.join(__file__, '../../lib/python')))

import argparse
from ssl import SSLError

from ovsdb_plugin.common import SEPARATOR
from ovsdb_plugin.mixins.loggable import LoggableMixin
from ovsdb_plugin.models.jmx import JMXPasswordFile
from ovsdb_plugin.models.keypair import Keypair
from ovsdb_plugin.utils import sdt
from ovsdb_plugin.utils.logger_setup import setup_logging


class Receive(object, LoggableMixin):

    def __init__(self):
        self.keypair = Keypair()
        self.jmx_file = JMXPasswordFile()

    def execute(self):
        # We don't provide the remote sender's CA cert to this instance of
        # SDTPeer since it will act as a server and does not need to verify
        # the sender's identity.
        local = sdt.SimpleDataTransferPeer(key_path=self.keypair.key_path,
                                           cert_path=self.keypair.crt_path,
                                           role=sdt.ROLE_RECEIVER)

        self._info('Waiting to receive keypair on port {} via SSL/TLS...'
                   .format(local.inport))

        # The remote sender, however, needs to verify this instance's identity
        # so we have to provide the CA cert to the administrator. The
        # administrator should copy that information and provide it to the
        # sender. This is important since we're sending sensitive information
        # (private key) over the network and we don't want that to be
        # compromised by a MITM attack.
        #
        # Notice how we're just reading the crt file as the CA cert. This
        # is because it's a self-signed crt file and self-signed crt files
        # serve as its own CA cert too.
        with open(self.keypair.crt_path, 'r') as cacertfile:
            cacert = cacertfile.read()

        self._info('\nProvide sender with my CA cert:\n{}'
                   .format(cacert))

        try:
            # Return a list containing keypair (index 0) and cert (index 1)
            data = local.receive().split(SEPARATOR, 2)
        except SSLError:
            self._error("Failed to verify remote host. Check that you "
                        "provided the correct CA cert.")
            return 1

        self._info("Keypair received from {}".format(local.remote))
        self._debug("Received: {}".format(data))

        # Save and convert the keypair to p12
        self.keypair.save(data[0], data[1])
        self.jmx_file.save(data[2])

        msg = 'OVSDB plugin keypair saved to \'{}\''
        self._info(msg.format(self.keypair.p12_path))

        return 0


if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument('--verbose', action='store_true')

    args = parser.parse_args()
    setup_logging(args.verbose, output='stdout')
    sys.exit(Receive().execute())
