#!/bin/env python

import json
import base64
import os, errno
import shutil
import datetime
import s3upload
import urllib2

# globals
FILENAME = "full_data.json"
BACKUP_DIR = "complete_consul_backup"
SCRIPT_DIR = os.getcwd()
consul_data = dict()
CONSUL_DATA_URL = "http://localhost:8500/v1/kv/?recurse"

# download the whole file in JSON
def generate_json_dump(url):
    '''
    returns the json dump from a url
    '''

    response = urllib2.urlopen(url)
    result = response.read()
    return result



# create recursive direcotries.
def mkdir_p(path):
    '''
    path ==> string

    returns true when function creates direcotries recursively
    '''
    try:
        os.makedirs(path) # create directory
        return True
    except OSError as exc:
        if exc.errno == errno.EEXIST and os.path.isdir(path):
            return False
        else:
            raise


def sanitize_key_values(key):
    '''
    key ==> string

    returns directory_hirearchy, variable_name from key
    '''
    variable_start_index = key.rfind("/")
    variable_name = key[variable_start_index + 1: ] # wil return variable name
    directory_hirearchy = key[:variable_start_index ] # create a hirearchy of directories

    return directory_hirearchy , variable_name


def write_to_file(directory, variable_value):
    '''
    directory_name ==> string,  variable_value ==> string

    returns true if all the values of in variable_value are successfully written
    to the file .
    '''

    [directory_hirearchy ,FILENAME ] = sanitize_key_values(directory)
    FILENAME = str(FILENAME) + ".yml"
    mkdir_p(directory_hirearchy) # create the directory
    base_path = os.getcwd()
    os.chdir(base_path  + "/" + directory_hirearchy)
    write_file = open(FILENAME, 'a')
    for k,v in sorted(variable_value.items() ):
        write_line  = str(k) + " : " + str(v) + "\n"
        write_file.write(write_line)
    write_file.close()
    os.chdir(base_path)
    # print "wrote the " + str(FILENAME) + " in " + base_path + "/"+ BACKUP_DIR + str(directory_hirearchy)
    print "wrote the " + str(FILENAME) + " in " +str(directory_hirearchy)

    return True


def add_to_dictionary(directory_hirearchy, variable_name, variable_value):
    '''
    key ==> string , variable_name ==> string, variable_value ==> string

    Alter a global dictionary of dictionaries  where directory_hirearchy is the key
    and value is a dictionary of form { variable_name :variable_value }

    '''
    global consul_data

    if directory_hirearchy not in consul_data :
        consul_data[directory_hirearchy] = {}
        consul_data[directory_hirearchy][variable_name] = variable_value
    else :
        consul_data[directory_hirearchy][variable_name] = variable_value

def zip_directory(zip_directory, zip_name, zip_path ):
    '''
    zip_directory ==> string, zip_name ==> string , zip_path ==> string

    returns true if a directory is zipped successfully
    '''
    try:
        zip_name = zip_path + "/" + zip_name
        zip_directory = zip_path + "/" + zip_directory
        shutil.make_archive(zip_name, "zip", zip_directory)
        return True
    except Exception as e:
        raise


# read the configs
configs = s3upload.read_config(s3upload.CONFIG_FILE)
if configs["CONSUL_DATA_URL"] != ""  :
    CONSUL_DATA_URL = configs["CONSUL_DATA_URL"]

# take json dump
result = generate_json_dump(CONSUL_DATA_URL)

# write to a file
write_file = open(FILENAME, 'w')
write_file.write(result)
write_file.close()

# open the dump file
read_file = open(FILENAME, 'r' )

# read and convert to list
lines = read_file.readlines()

# parsing the json and converting to list
# data is the list of dictionaries
data = json.loads(lines[0])


# one_value ==> dict, data ==> list
for one_value in data :
    value = one_value["Value"]
for one_value in data :
    value = one_value["Value"]
    if value is not None :
        key = one_value["Key"]
        value = str(base64.b64decode(value))
        struct = sanitize_key_values(key)

        # assign directory and variable names and values
        directory_hirearchy = struct[0]
        variable_name = struct[1]
        variable_value = value

        # print directory_hirearchy, variable_name, variable_value
        add_to_dictionary( directory_hirearchy, variable_name, variable_value )

        # print key , value
    else :
        pass


# create and move to a new backup directory
mkdir_p(BACKUP_DIR)
os.chdir(BACKUP_DIR)

# write the values to a backup directory
for key, value  in consul_data.items() :
            write_to_file(key, value )
read_file.close()

# change to script directory
os.chdir(SCRIPT_DIR)

# compress the backup directory
base_path = os.getcwd()
zip_name = str(BACKUP_DIR) + "_" + str(datetime.datetime.now().date() )
zip_directory(BACKUP_DIR, zip_name, base_path)
UPLOAD_FILE_PATH = base_path + "/" + zip_name + ".zip"
#s3upload.upload_S3(UPLOAD_FILE_PATH)
s3upload.upload_S3(zip_name + ".zip")
