from functools import cached_property
from http.cookies import SimpleCookie
from http.server import BaseHTTPRequestHandler
from urllib.parse import parse_qsl, urlparse
import json

from http.server import HTTPServer, BaseHTTPRequestHandler

class WebRequestHandler(BaseHTTPRequestHandler):
	def __init__(self, request, client_address, server):
		BaseHTTPRequestHandler.__init__(self, request, client_address, server)

	@cached_property
	def url(self):
		return urlparse(self.path)

	@cached_property
	def query_data(self):
		return dict(parse_qsl(self.url.query))

	@cached_property
	def post_data(self):
		content_length = int(self.headers.get("Content-Length", 0))
		return self.rfile.read(content_length)

	@cached_property
	def form_data(self):
		return dict(parse_qsl(self.post_data.decode("utf-8")))

	@cached_property
	def cookies(self):
		return SimpleCookie(self.headers.get("Cookie"))

	def get_master_page_header(self, page_title):
		return """<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
	<head>
		<title>""" + page_title + """</title>
		<link rel="stylesheet" type="text/css" href="/css/uwt.css" />
	</head>
	<body>"""

	def get_master_page_footer(self):
		return "</body></html>"

	def write(self, text):
		self.wfile.write(text.encode("utf-8"))

	def write_file(self, filename):
		with open(filename, mode='rb') as f:
			lines = f.read()
			
		self.wfile.write(lines)

	def write_file_text(self, filename):
		with open(filename, mode='r') as f:
			lines = f.read()
			
		self.wfile.write(lines.encode("utf-8"))

	def execute_shell_return_stdout(self, command):
		import os
		p = os.popen(command)
		ret = p.read().strip()
		return ret

	def get_column_headings(self):
		return [
			'Instance ID',
			'Description',
			'State',
			# Orch Manager
			'Tenants',
			'Info',
			'Disposition Time',
			'Up Time',
			'Password',
			'Actions'
		]
	
	def get_column_data(self, instanceId):
		status = self.execute_shell_return_stdout("mocha suv status " + instanceId).split(':')
		primaryStatus = status[0].strip()
		secondaryStatus = ""
		if len(status) > 1:
			secondaryStatus = status[1].strip()

		description = self.execute_shell_return_stdout("mocha suv shell " + instanceId + " -c 'mocha suv description'")
		if description == "":
			description = "(none)"

		tenantsHtml = ""
		tenantsStr = self.execute_shell_return_stdout("mocha suv shell " + instanceId + " -c 'mocha oms tenant list names'")
		tenants = tenantsStr.split('\n')
		for tenant in tenants:
			if tenant != "":
				tenantsHtml += "<a target=\"_blank\" href=\"https://" + instanceId + ".privatesuv.com/" + tenant + "\">" + tenant + " <i class=\"uwt-icon fa fa-arrow-up-right-from-square\"></i></a><br />"
		

		startTimeStr = self.execute_shell_return_stdout("mocha suv shell " + instanceId + " -c 'cat /etc/mocha/suvstart'").strip()
		upTimeStr = ""
		buttonsHtml = ""
		
		if startTimeStr != '':
			print("startTimeStr = '" + startTimeStr + "'")
			from datetime import datetime
			startTime = datetime.fromisoformat(startTimeStr)
			currentTime = datetime.now()

			upTime = (currentTime - startTime)

			from math import floor
			
			secs = floor(upTime.seconds % 60)
			mins = floor((upTime.seconds / 60) % 60)
			hrs = floor((upTime.seconds / (60 * 60)) % 24)
			

			upTimeStr = str(upTime.days) + "d " + str(hrs) + "h " + str(mins) + "m " + str(secs) + "s"
		else:
			upTimeStr = "(not running)"

		if primaryStatus == "stopped":
			buttonsHtml += "<a href=\"/my-suvs/" + instanceId + "/start\">Start</a>"
		else:
			buttonsHtml += "<a href=\"/my-suvs/" + instanceId + "/stop\">Stop</a>"
			
		buttonsHtml += " <a href=\"/my-suvs/" + instanceId + "/restart\">Restart</a> <a href=\"/my-suvs/" + instanceId + "/terminate\">Terminate</a>"

		return [
			instanceId,
			description,
			"<strong>" + primaryStatus + "</strong><br />" + secondaryStatus,
			# "Orch Manager",
			tenantsHtml,
			"2023.11.10<br />master",
			# Disposition Time
			"Stops In: none",
			# Up Time
			"<!-- " + startTimeStr + " -->" + upTimeStr,
			"<div style=\"text-align: center;\"><a href=\"#\"><i class=\"fa fa-key\"></i></a></div>",
			buttonsHtml
		]
	def get_application_title(self) -> str:
		return "SUV Manager"

	def write_suv_entry(self, instanceId):
		columns = self.get_column_data(instanceId)
		self.write("<tr>")
		for column in columns:
			self.write("<td>" + column + "</td>")
		self.write("</tr>")

	def build_self_service_details(self, instance_id):
		tenantsHtml = ""
		tenantsStr = self.execute_shell_return_stdout("mocha suv shell " + instance_id + " -c 'mocha oms tenant list names'")
		tenants = tenantsStr.split('\n')
		for tenant in tenants:
			if tenant != "":
				tenantsHtml += "<a target=\"_blank\" href=\"https://" + instance_id + ".privatesuv.com/" + tenant + "\">" + tenant + " <i class=\"uwt-icon fa fa-arrow-up-right-from-square\"></i></a>"
				if (tenants.index(tenant) < len(tenants) - 1):
					tenantsHtml += ", "
		
		return [
			{
				"title": "General",
				"actions": [
					{
						"icon": "",
						"title": "SUV Logs",
						"href": "#"
					}
				],
				"properties": {
					"Name": "suv",
					"Instance ID": instance_id,
					"Host Name": instance_id + ".privatesuv.com",
					"Environment Version": "584026",
					"Confidence Level": "prod",
					"Status": { "backgroundColor": "#aaffaa", "value": "completed" }
				}
			},
			{
				"title": "Data Manager",
				"actions": [
					{
						"icon": "",
						"title": "Reset Tenants",
						"href": "#"
					}
				],
				"properties": {
					"Tenants": tenantsHtml,
					"Tenant Version": "2023.11.12"
				}
			},
			{
				"title": "MySQL",
				"properties": {
					"User": "root",
					"Host": "localhost",
					"Port": 3306,
					"Status": { "backgroundColor": "#aaffaa", "value": "running" }
				}
			}
		]
			
	def do_GET(self):

		path = self.url.path.split('/')
		path = path[1:]

		if path[0] == "":

			self.send_response(200)
			self.send_header("Content-Type", "application/xhtml+xml")
			self.end_headers()

			self.write(self.get_master_page_header(self.get_application_title()))
			self.write("<h1>It works</h1>")
			self.write(self.get_master_page_footer())

		elif path[0] == "css":

			if path[1] == "uwt.css":

				self.write_file_text("/usr/share/mocha/suv-manager/css/uwt.css")

		elif path[0] == "common":
			
			if path[1] == "fonts":

				if path[2] == "awesome":

					if path[3] == "css":

						if path[4] == "all.min.css":

							self.write_file("/usr/share/mocha/suv-manager/common/fonts/awesome/css/all.min.css")
					
					elif path[3] == "webfonts":

						self.write_file("/usr/share/mocha/suv-manager/common/fonts/awesome/webfonts/" + path[4])

		elif path[0] == "my-suvs":

			if (len(path) == 1 or (len(path) == 2 and path[1] == "")):

				self.send_response(200)
				self.send_header("Content-Type", "application/xhtml+xml")
				self.end_headers()
				
				self.write(self.get_master_page_header("My SUVs - " + self.get_application_title()))
				self.write("""
				<div class="uwt-panel">
					<div class="uwt-content">
						<h1>My SUVs</h1>
						<div class="uwt-toolbar">
							<a href="#" class="uwt-button uwt-color-primary"><i class="uwt-icon fa fa-add"></i><span class="uwt-title">Create SUV</span></a>
						</div>
						<table class="uwt-listview uwt-expand">
							<thead>
								<tr>""")
				
				for column in self.get_column_headings():
					self.write("<th> " + column + "</th>")

				self.write("""</tr></thead><tbody>""")

				suv_list = self.execute_shell_return_stdout("mocha suv list").split('\n')
				for suv in suv_list:
					if suv != "":
						self.write_suv_entry(suv)

				self.write("""
							</tbody>
						</table>
					</div>
				</div>
				""")
				self.write(self.get_master_page_footer())
			
			elif len(path) == 2:

				self.write("My SUVs SUV Page for " + path[1])

			elif len(path) == 3:

				if path[2] == "stop":

					self.execute_shell_return_stdout("mocha suv down " + path[1])
					self.send_response(302)
					self.send_header("Location", "/my-suvs")
					self.end_headers()
				
				elif path[2] == "start":

					self.execute_shell_return_stdout("mocha suv up " + path[1])
					self.send_response(302)
					self.send_header("Location", "/my-suvs")
					self.end_headers()
				
				elif path[2] == "self-service":

					suv_inst_id = path[1]
					suv_confidence_level = 'prod'

					self.send_response(200)
					self.send_header("Content-Type", "application/xhtml+xml")
					self.end_headers()
					
					self.write(self.get_master_page_header("SUV Self Service - " + self.get_application_title()))

					self.write("<h1>SUV Self Service</h1>")

					self_service = self.build_self_service_details(path[1])

					for self_service_panel in self_service:
						self.write("""<div class="uwt-panel"><div class="uwt-header"><h2>""" + self_service_panel["title"] + """</h2></div><div class="uwt-content"><div class="uwt-toolbar">""")

						if "actions" in self_service_panel:
							for self_service_action in self_service_panel["actions"]:
								self.write("""<a href=\"""" + self_service_action["href"] + """\" class="uwt-button uwt-color-primary"><i class="uwt-icon fa fa-""" + self_service_action["icon"] + """\"></i><span class="uwt-title">""" + self_service_action["title"] + """</span></a>""")
						
						self.write("</div>")
						self.write("""<table class="uwt-listview uwt-expand"><thead><tr><th style="width: 50%">Property</th><th>Value</th></tr></thead><tbody>""")
						
						if "properties" in self_service_panel:
							for name in self_service_panel["properties"]:
								value = self_service_panel["properties"][name]
								val = ""
								
								if (isinstance(value, dict)):
									self.write("<tr><td>" + name + "</td>")
									if "backgroundColor" in value:
										self.write("<td style=\"background-color: " + value["backgroundColor"] + "\">")
									else:
										self.write("<td>")

									self.write(str(value["value"]) + "</td></tr>")
								else:
									self.write("<tr><td>" + name + "</td><td>" + str(value) + "</td></tr>")
						
						self.write("</tbody></table></div></div>")


					self.write(self.get_master_page_footer())
				
				else:

					self.write("My SUVs Action (" + path[2] + ") Page for " + path[1])


		else:

			self.send_response(404)
			self.end_headers()
			self.write("Not Found")
		
if __name__ == "__main__":

	port = 61381
	print("Mocha User Interface Service - running on port", port)

	server = HTTPServer(("127.0.0.1", port), WebRequestHandler)
	server.serve_forever()

