# Copyright (c) 2022, JINGROW
# For license information, please see license.txt

import jingrow
from jingrow.utils import rounded

from jcloud.api.server import calculate_swap, prometheus_query, total_resource, usage


def execute(filters=None):
	jingrow.only_for("System Manager")
	columns = [
		{
			"fieldname": "server",
			"label": jingrow._("Server"),
			"fieldtype": "Link",
			"options": "Server",
			"width": 200,
		},
		{
			"fieldname": "cpu",
			"label": jingrow._("vCPUs"),
			"fieldtype": "Int",
			"width": 100,
		},
		{
			"fieldname": "cpu_used",
			"label": jingrow._("CPU Utilization(%)"),
			"fieldtype": "Float",
			"width": 100,
		},
		{
			"fieldname": "disk",
			"label": jingrow._("Space (GB)"),
			"fieldtype": "Float",
			"width": 100,
		},
		{
			"fieldname": "disk_used",
			"label": jingrow._("Space Used(%)"),
			"fieldtype": "Float",
			"width": 100,
		},
		{
			"fieldname": "disk_free",
			"label": jingrow._("Space Free (GB)"),
			"fieldtype": "Float",
			"width": 100,
		},
		{
			"fieldname": "memory",
			"label": jingrow._("Memory (GB)"),
			"fieldtype": "Float",
			"width": 100,
		},
		{
			"fieldname": "memory_used",
			"label": jingrow._("Memory Used(%)"),
			"fieldtype": "Float",
			"width": 100,
		},
		{
			"fieldname": "swap",
			"label": jingrow._("Swap (GB)"),
			"fieldtype": "Float",
			"width": 100,
		},
		{
			"fieldname": "swap_used",
			"label": jingrow._("Swap Used(%)"),
			"fieldtype": "Float",
			"width": 100,
		},
		{
			"fieldname": "memory_required",
			"label": jingrow._("Memory Required (GB)"),
			"fieldtype": "Float",
			"width": 100,
		},
		{
			"fieldname": "memory_shortage",
			"label": jingrow._("Memory Shortage (GB)"),
			"fieldtype": "Float",
			"width": 100,
		},
		{
			"fieldname": "ram_assigned",
			"label": jingrow._("Ram Assigned for Workers (GB)"),
			"fieldtype": "Float",
			"width": 100,
		},
		{
			"fieldname": "new_worker_allocation",
			"label": jingrow._("New Worker Allocation"),
			"fieldtype": "Check",
			"width": 100,
		},
		{
			"fieldname": "load_1",
			"label": jingrow._("Load Average 1 (%)"),
			"fieldtype": "Float",
			"width": 100,
		},
		{
			"fieldname": "load_5",
			"label": jingrow._("Load Average 5 (%)"),
			"fieldtype": "Float",
			"width": 100,
		},
		{
			"fieldname": "load_15",
			"label": jingrow._("Load Average 15 (%)"),
			"fieldtype": "Float",
			"width": 100,
		},
	]

	data = get_data()
	return columns, data


def calculate_load(server):
	query_map = {
		"load_1": (
			f"""avg(node_load1{{instance="{server}", job="node"}}) / count(count(node_cpu_seconds_total{{instance="{server}", job="node"}}) by (cpu)) * 100""",
			lambda x: x,
		),
		"load_5": (
			f"""avg(node_load5{{instance="{server}", job="node"}}) / count(count(node_cpu_seconds_total{{instance="{server}", job="node"}}) by (cpu)) * 100""",
			lambda x: x,
		),
		"load_15": (
			f"""avg(node_load15{{instance="{server}", job="node"}}) / count(count(node_cpu_seconds_total{{instance="{server}", job="node"}}) by (cpu)) * 100""",
			lambda x: x,
		),
	}

	result = {}
	for usage_type, query in query_map.items():
		response = prometheus_query(query[0], query[1], "Asia/Kolkata", 120, 120)["datasets"]
		if response:
			result[usage_type] = response[0]["values"][-1]
	return result


def get_data():
	servers = jingrow.db.sql_list(
		"""
		select
			server.name
		from
			tabServer server
		where
			(
				server.team like "%%jingrow.com"
				or server.team = ""
			)
			and server.provider = "AWS EC2"
			and status = "Active"
		"""
	)

	rows = []
	for server in servers:
		used_data = usage(server)
		available_data = total_resource(server)
		swap_memory = calculate_swap(server)
		load = calculate_load(server)

		rows.append(
			{
				"server": server,
				"cpu": available_data.get("vcpu", 0),
				"cpu_used": rounded(used_data.get("vcpu", 0) * 100, 1),
				"disk": rounded(available_data.get("disk", 0), 2),
				"disk_used": rounded(
					(used_data.get("disk", 0) / available_data.get("disk", 1)) * 100, 1
				),
				"disk_free": available_data.get("disk", 0) - used_data.get("disk", 0),
				"memory": rounded(available_data.get("memory", 0) / 1024, 2),
				"memory_used": rounded(
					(used_data.get("memory", 0) / available_data.get("memory", 1)) * 100, 1
				),
				"swap": rounded(swap_memory.get("swap", 0), 1),
				"swap_used": rounded(swap_memory.get("swap_used", 0), 1),
				"memory_required": rounded(swap_memory.get("required", 0), 1),
				"memory_shortage": max(
					rounded(swap_memory.get("required", 0), 1)
					- rounded(available_data.get("memory", 0) / 1024, 2),
					0,
				),
				"new_worker_allocation": jingrow.db.get_value(
					"Server", server, "new_worker_allocation"
				),
				"ram_assigned": (jingrow.db.get_value("Server", server, "ram") or 0) / 1024,
				"load_1": rounded(load.get("load_1", 0), 1),
				"load_5": rounded(load.get("load_5", 0), 1),
				"load_15": rounded(load.get("load_15", 0), 1),
			}
		)

	return rows
