#!/usr/bin/python3
#
# MySQL client wrapper for safe password storage in the keyring.

import argparse
import getpass
import os
import secretstorage
import tempfile
import urllib.parse
try:
    # Local module with some defaults
    from booking.odbc import OdbcConnector
except ImportError:
    class OdbcConnector:
        def to_url(self, schema):
            return urllib.parse.urlparse(self.default_url + schema)
        default_url = 'mysql://localhost/'

class MysqlWrapper(OdbcConnector):
    def __init__(self, schema):
        self.url = self.to_url(schema)
        self.bus = secretstorage.dbus_init()
        self.collection = secretstorage.get_default_collection(self.bus)

    def connect(self):
        username, password = self.get_login(self.url.geturl())
        if not username:
            username, password = self.get_login(self.default_url)
            if not username:
                username = input("Username for %s: " % self.url.netloc)
                password = getpass.getpass("Password for %s: " % self.url.netloc)
            self.save_login(username, password)
        args = [
            # Connection info
            'host=%s' % self.url.netloc,
            'user=%s' % username,
            'database=' + self.url.path[1:],
            'password=' + password,
            # SSL/auth settings
            'enable-cleartext-plugin',
            'ssl-ca=' + os.path.expanduser('~/.config/ssl/booking-server-ca.crt'),
            # Nice prompt
            r'prompt=\u@\d>\\_',
            # Too many tables
            'no-auto-rehash',
        ]
        # Use an anonymous tempfile for communicating
        temp = tempfile.TemporaryFile()
        os.set_inheritable(temp.fileno(), True)
        temp.write(('[client]\n' + '\n'.join(args)).encode('utf-8'))
        temp.seek(0, os.SEEK_SET)
        os.execv('/usr/bin/mysql', ['mysql', '--defaults-extra-file=/dev/fd/%d' % temp.fileno()])

    def get_login(self, hostname):
        items = list(self.collection.search_items({'hostname': hostname}))
        if not items:
            return None, None
        return (items[0].get_attributes()['username'], items[0].get_secret().decode('utf-8'))

    def save_login(self, username, password):
        self.collection.create_item(self.url.geturl(), {'hostname': self.url.geturl(), 'username': username}, password, True)


ap = argparse.ArgumentParser()
ap.add_argument('schema')
args = ap.parse_args()
MysqlWrapper(args.schema).connect()
