#!/usr/libexec/platform-python

import os
import sys
import json
import subprocess
import io
from shutil import copyfile
from contextlib import redirect_stdout
from datetime import datetime
import copy
import fileinput
import re

g_param_file_path = "/usr/share/cockpit/ceph-deploy/params/core_params.json"
g_param_file_dir = "/usr/share/cockpit/ceph-deploy/params"
g_rgwloadbalancers_file_path = "/usr/share/cockpit/ceph-deploy/ceph-ansible-files/rgwloadbalancers.yml"
g_rgwloadbalancers_file_dir = "/usr/share/cockpit/ceph-deploy/ceph-ansible-files"
g_ansible_file_path = "/usr/share/ceph-ansible/group_vars/rgwloadbalancers.yml"
g_inventory_file_key = "rgwloadbalancers.yml"

def print_to_string(item):
	with io.StringIO() as buf, redirect_stdout(buf):
		print(item)
		output = buf.getvalue().rstrip("\n")
		return output

def get_parameters(path):
	if os.path.exists(path) and os.path.isfile(path):
		#file exists on disk, load contents and return json object.
		f = open(path,"r")
		param_file_content = print_to_string(f.read())
		f.close()
		try:
			parsed_json = json.loads(param_file_content)
		except ValueError as err:
			# failed to get json from command line arguments
			error_string = print_to_string(err)
			error_msg = { "error_msg":"JSON Parse Error ({p}): ".format(p=g_param_file_path) + error_string }
			print(json.dumps(error_msg,indent=4))
			update_inventory_state(g_inventory_file_key,g_ansible_file_path,True)
			sys.exit(1)
		return parsed_json
	else:
		error_msg = { "error_msg":"File not found ({p}): ".format(p=path) }
		print(json.dumps(error_msg,indent=4))
		update_inventory_state(g_inventory_file_key,g_ansible_file_path,True)
		sys.exit(1)

def make_rgwloadbalancers(rgwlb_dict,path,dir,ansible_path):
	if not os.path.exists(dir):
		os.makedirs(dir)
	if os.path.exists(path) and os.path.isfile(path):
		os.remove(path)

	rgwlb_file_content = ["---\n\n"]
	if "haproxy_frontend_port" in rgwlb_dict.keys():
		rgwlb_file_content.append("haproxy_frontend_port: " + rgwlb_dict["haproxy_frontend_port"] + "\n")
	if "virtual_ips" in rgwlb_dict.keys() and len(rgwlb_dict["virtual_ips"]) > 0:
		rgwlb_file_content.append("virtual_ips: " + "\n")
		for ip in rgwlb_dict["virtual_ips"]:
			rgwlb_file_content.append("   - " + ip + "\n")
	if "virtual_ip_netmask" in rgwlb_dict.keys():
		rgwlb_file_content.append("virtual_ip_netmask: " + rgwlb_dict["virtual_ip_netmask"]+ "\n")
	if "virtual_ip_interface" in rgwlb_dict.keys():
		rgwlb_file_content.append("virtual_ip_interface: " + rgwlb_dict["virtual_ip_interface"] + "\n")

	if "enable_ssl" in rgwlb_dict.keys() and rgwlb_dict["enable_ssl"] == True:
			if "haproxy_frontend_ssl_port" in rgwlb_dict.keys():
				rgwlb_file_content.append("haproxy_frontend_ssl_port: " + rgwlb_dict["haproxy_frontend_ssl_port"] + "\n")
			if "haproxy_frontend_ssl_certificate" in rgwlb_dict.keys():
				rgwlb_file_content.append("haproxy_frontend_ssl_certificate: " + rgwlb_dict["haproxy_frontend_ssl_certificate"] + "\n")
			if "haproxy_ssl_dh_param" in rgwlb_dict.keys():
				rgwlb_file_content.append("haproxy_ssl_dh_param: " + rgwlb_dict["haproxy_ssl_dh_param"] + "\n")
			if "haproxy_ssl_ciphers" in rgwlb_dict.keys() and len(rgwlb_dict["haproxy_ssl_ciphers"]) > 0:
				rgwlb_file_content.append("haproxy_ssl_ciphers: " + "\n")
				for entry in rgwlb_dict["haproxy_ssl_ciphers"]:
					rgwlb_file_content.append("   - " + entry + "\n")
			if "haproxy_ssl_options" in rgwlb_dict.keys() and len(rgwlb_dict["haproxy_ssl_options"]) > 0:
				rgwlb_file_content.append("haproxy_ssl_options: " + "\n")
				for entry in rgwlb_dict["haproxy_ssl_options"]:
					rgwlb_file_content.append("   - " + entry + "\n")
			

	rgwlb_file = open(path,"w")
	rgwlb_file.writelines(rgwlb_file_content)
	rgwlb_file.close()

	# overwrite the rgwloadbalancers.yml file in the ceph-ansible/groupvars directory.
	try:
		copyfile(path,ansible_path)
	except OSError as err:
		# print json formatted error
		error_string = print_to_string(err)
		error_msg = { "error_msg":error_string}
		print(json.dumps(error_msg,indent=4))
		update_inventory_state(g_inventory_file_key,g_ansible_file_path,True)
		sys.exit(1)

def update_inventory_state(key,path,failed):
    inv_state_file_path = "/usr/share/cockpit/ceph-deploy/state/inventory_state.json"
    inv_state_file_dir = "/usr/share/cockpit/ceph-deploy/state"

    date = datetime.today()
    time = datetime.now()
    timestamp =  date.strftime("%Y-%m-%d") + time.strftime("-%H-%M")

    state_dict = {}

    new_state = {
        "path":path,
        "failed": failed,
        "timestamp": timestamp
    }

    # check to see if file needs to be created.
    if not os.path.exists(inv_state_file_path):
        # file doesn't exist
        if not os.path.exists(inv_state_file_dir):
            # file directory doesn't exist, make required directories
            os.makedirs(inv_state_file_dir)
        #create new inv state file with default parameters
        state_file = open(inv_state_file_path,"w")
        state_file.write(json.dumps(state_dict,indent=4))
        state_file.close()

    else:
        #file exists on disk, load contents and return json object.
        state_file = open(inv_state_file_path,"r")
        state_file_content = print_to_string(state_file.read())
        state_file.close()
        state_dict = json.loads(state_file_content)
    
    state_dict[key] = copy.deepcopy(new_state)
    state_file = open(inv_state_file_path,"w")
    state_file.write(json.dumps(state_dict,indent=4))
    state_file.close()

def main():
	global g_param_file_path
	global g_param_file_dir
	global g_rgwloadbalancers_file_path
	global g_all_default_file_path
	global g_ansible_file_path
	global g_inventory_file_key
	params = get_parameters(g_param_file_path)
	if "groups" in params.keys() and "rgwloadbalancers" in params["groups"].keys():
		make_rgwloadbalancers(params["groups"]["rgwloadbalancers"],g_rgwloadbalancers_file_path,g_rgwloadbalancers_file_dir,g_ansible_file_path)
	else:
		error_msg = { "error_msg":"Unable to create rgwloadbalancers.yml"}
		print(json.dumps(error_msg,indent=4))
		update_inventory_state(g_inventory_file_key,g_ansible_file_path,True)
		sys.exit(1)
	success_msg = { "success_msg":"rgwloadbalancers.yml file created successfully","path":g_ansible_file_path}
	print(json.dumps(success_msg,indent=4))
	update_inventory_state(g_inventory_file_key,g_ansible_file_path,False)
	sys.exit(0)

if __name__ == "__main__":
	main()