import json
import platform
from context import GenericServerError, InvalidRequestMethodError
from server_modules.util import *
import server_modules.index
import server_modules.eas
import server_modules.elasticsearch
import server_modules.data_overview
import server_modules.hardware_info
import server_modules.serverconfig

def process_request(easydb_context, parameters):
    loggerprefix = "pf.plugin.base.server"
    method = parameters['method']
    if method != 'GET':
        raise InvalidRequestMethodError(method)
    easydb_context.check_system_right('system.server.status')
    instance = easydb_context.get_instance()
    db_cursor = easydb_context.get_db_cursor()
    config = easydb_context.get_config()
    body = get_system_info(easydb_context, db_cursor, loggerprefix)
    tabs = {
        'data_overview': server_modules.data_overview.get_info,
        'index': server_modules.index.get_info,
        'eas': server_modules.eas.get_info,
        'elasticsearch': server_modules.elasticsearch.get_info,
        'serverconfig': server_modules.serverconfig.get_info
    }
    for name, function in list(tabs.items()):
        body['info_groups'].append({'name': name, 'info': function(easydb_context, db_cursor, config, instance, loggerprefix + "." + name)})
    return {
        'status_code': 200,
        'body': json.dumps(body, indent=4),
        'headers': {
            'Content-Type': 'application/json; charset=utf-8'
        }
    }

def get_system_info(easydb_context, db_cursor, loggerprefix):
    infos = []

    logger = easydb_context.get_logger(loggerprefix + ".system_info")

    # general system information
    db_cursor.execute(sql_get_uptime)
    rows = db_cursor.fetchall()
    if len(rows) > 0:
        now = rows[0]['now']
        uptime = rows[0]['uptime']
    else:
        now = '<unknown>'
        uptime = 0
    logger.debug("now: %s, uptime: %s" % (now, uptime))

    infos.append(make_map('general', [
        make_data('integer', 'uptime', uptime, 's'),
        make_data('string', 'api-version', '1'),
        make_data('string', 'software-version', '1'),
        make_data('string', 'os-version', platform.platform())
    ]))

    # cpu, ram, disk information
    for cpu_info in server_modules.hardware_info.get_cpu_info(easydb_context.get_logger(loggerprefix + ".cpu_info")):
        infos.append(cpu_info)
    for ram_info in server_modules.hardware_info.get_ram_info(easydb_context.get_logger(loggerprefix + ".ram_info")):
        infos.append(ram_info)
    try:
        infos.append(server_modules.hardware_info.get_disk_info(easydb_context.get_logger(loggerprefix + ".disk_info")))
    except OSError as e:
        easydb_context.get_logger(loggerprefix + ".disk_info").error("failed to get disk info: {}".format(e))

    return {
        '_server_time': now,
        'info_groups': [{
            'name': 'system',
            'info': infos
        }]
    }

sql_get_uptime = """\
SELECT to_char(now(), 'IYYY-MM-DD"T"HH24:MI:SS') || to_char(extract(timezone_hour from now()), 'S09') || ':' || to_char(extract(timezone_minute from now()), 'FM09') AS now,
    cast(extract(epoch from (now() - created_timestamp)) as integer) AS uptime
FROM ez_event
WHERE type = 'SERVER_START'
ORDER BY created_timestamp DESC
LIMIT 1
"""
