#!/usr/bin/python

"""
Copyright (c) 2011-2013 Yubico AB
All rights reserved.

Redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following
conditions are met:

    1. Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.
    2. Redistributions in binary form must reproduce the above
    copyright notice, this list of conditions and the following
    disclaimer in the documentation and/or other materials provided
    with the distribution.
    
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
"""



import os
import sys
import io
import hashlib
import re
import time
import errno
import argparse


try:
    from sqlalchemy import create_engine, Table, MetaData 
except ImportError: 
    print "Please, install SQLAlchemy. Follow instruction in README.db.import-export file."
    sys.exit(1)


from os.path import abspath

sys.path.append('Lib')
from pyhsm.util import key_handle_to_int
#from pyhsm.yubikey import modehex_decode
import pyhsm.aead_cmd

##########################
# Functions Declarartion #
##########################




#
# reconstruct a database url with the valid username and password
#
def build_database_url(databaseUrl, dbusername, dbpassword):

    #urltype mysql://user:pass@localhost/dbname
    result = re.search(r'@', databaseUrl)
    if result:
        result = re.sub(r'://.*?@', '://'+dbusername+":"+dbpassword+"@", databaseUrl)
        if result:
            return result
        else:
            print "FATAL: Malformed database url. A valid url looks like this: mysql://username:password@hostname/dbname"
            sys.exit(1)
        
    else:
        result = re.search(r'(.*?://)(.*?/)(.+)', databaseUrl)
        if result:
            databaseUrl = result.group(1)+dbusername+":"+dbpassword+"@"+result.group(2)+result.group(3)
            return databaseUrl
        
        else:
            print "FATAL: Malformed database url. A valid url looks like this: mysql://username:password@hostname/dbname"
            sys.exit(1)


#
#insert_slash insert / every 2 char
#
def insert_slash(string, every=2):
    return '/'.join(string[i:i+every] for i in xrange(0, len(string), every))

#
#mkdir -p: creates path like mkdir -p
#
def mkdir_p(path):
    try:
        os.makedirs(path)
    except OSError as exc:
        if exc.errno == errno.EEXIST and os.path.isdir(path):
            pass
        else: raise
        




#################################
# END of functions declariation #
#################################
                            





        
        
        
#######################
#                     #
# Initialization Area #
#                     #
#######################

parser = argparse.ArgumentParser(description='Import AEADs into the database')

parser.add_argument('path', action="store", type=str)
parser.add_argument('dburl', action="store")
args = vars(parser.parse_args())


if len(sys.argv) != 3:
    print("\nUsage: python export_aeads.py /path/to/export/ database_url\ni.e. python export_aeads.py /root/aeads/ mysql://root:password@localhost:3306/database_name")
    sys.exit(2)
    
if not os.path.isdir(sys.argv[1]):
    print("\nInvalid path, check your spelling.\n")
    sys.exit(2)

#set the path
path = args['path']
#mysql url
databaseUrl = args['dburl']

try:
    #check database connection
    engine = create_engine(databaseUrl)

    #SQLAlchemy voodoo
    metadata = MetaData()
    aeadobj = Table('aead_table', metadata, autoload=True, autoload_with=engine)
    connection = engine.connect()

except:
    print "\nPlease provide a valid database username"
    dbusername = raw_input(">>")
    print "\nPlease provide a valid database password:"
    dbpassword = raw_input(">>")
    
    try:
        #rebuild the url with given username and password
        databaseUrl = build_database_url(databaseUrl, dbusername, dbpassword)
        
        #check database connection
        engine = create_engine(databaseUrl)
        
        #SQLAlchemy voodoo
        metadata = MetaData()
        aeadobj = Table('aead_table', metadata, autoload=True, autoload_with=engine)
        connection = engine.connect()
    
    
    except:
        print "FATAL: Please provide valid username and password and a valid address i.e. mysql://localhost/dbname"
        sys.exit(1)
                                                                                                                      




aead = None
nonce = None
key_handle = None

aead = pyhsm.aead_cmd.YHSM_GeneratedAEAD(nonce, key_handle, aead)

#get data from the database   
result = connection.execute("SELECT * from aead_table")

#cycle through resutls
for row in result:

    #read values row by row
    aead.data = row['aead']
    publicId = row['public_id']
    aead.key_handle = row['keyhandle']
    aead.nonce = row['nonce']

    #os.path.join(path, [keyhandle, [insert_slash(publicId)]])
    path = ''.join([path, '/', str(hex(aead.key_handle)).rstrip('L'), '/', insert_slash(publicId)])
    #sanitize path
    path = os.path.normpath(path)
    #create path
    mkdir_p(path)

    #write the file in the path
    pyhsm.aead_cmd.YHSM_GeneratedAEAD.save(aead, path+'/'+publicId)
    

    #reset path constructor
    path = sys.argv[1]
    
    



#close connection    
connection.close()

#exit without error
sys.exit(0)
