#!/bin/env python

import argparse
import requests
import json

import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)


class BMC:
    def __init__(self, server):
        self.url = "https://{0}/".format(server)
        self.session = requests.Session()
        self.login()

    def login(self):
        r = self.session.post(self.url + 'login',
                              json={'data': ['root', '0penBmc']},
                              verify=False)
        j = r.json()
        if j['status'] != 'ok':
            raise Exception("Failed to login: \n" + r.text)

    def list_events(self):
        r = self.session.get(self.url + 'xyz/openbmc_project/logging/entry/',
                             verify=False)
        j = r.json()
        if j['status'] != 'ok':
            raise Exception("Failed to query entries: \n" + r.text)

        events = j['data']
        events.sort(key=lambda x: int(x.split("/")[-1]))

        return events

    def get_event(self, event):
        r = self.session.get(self.url + event, verify=False)

        j = r.json()
        if j['status'] != 'ok':
            raise Exception("Failed to get event " + event + ": \n" + r.text)

        return j['data']
    
    def clear_event(self,event):
        r = self.session.delete(self.url + event)
        j = r.json()
        if j['status'] != 'ok':
            raise Exception("Failed to clear event " + event + ": \n" + r.text)

    def list_dumps(self):
        r = self.session.get(self.url + 'xyz/openbmc_project/dump/entry/',
                             verify=False)
        j = r.json()
        if j['status'] != 'ok':
            raise Exception("Failed to list dumps: \n" + r.text)

        dumps = j['data']
        dumps.sort(key=lambda x: int(x.split("/")[-1]))

        return dumps
    
    def create_dump(self):
        r = self.session.post(self.url + 'xyz/openbmc_project/dump/action/CreateDump')
        j = r.json()
        if j['status'] != 'ok':
            raise Exception("Failed to create dump: \n" + r.text)
        
    def get_dump(self,dump):
        r = self.session.get(self.url + dump,
                             verify=False)
        j = r.json()
        if j['status'] != 'ok':
            raise Exception("Failed to get dump " + event + ": \n" + r.text)

    def clear_dump(self,dump):
        r = self.session.delete(self.url + dump)
        j = r.json()
        if j['status'] != 'ok':
            raise Exception("Failed to clear dump " + dump + ": \n" + r.text)        

def do_list_events(args):
    s = BMC(server=args.server)
    for e in s.list_events():
        print(e)


def do_view_event(args):
    s = BMC(server=args.server)
    print(s.get_event(args.event))
    print json.dumps(s.get_event(args.event), indent=4)

def do_clear_event(args):
    s = BMC(server=args.server)
    s.clear_event(args.event)

def do_list_dumps(args):
    s = BMC(server=args.server)
    for e in s.list_dumps():
        print(e)

def do_create_dump(args):
    s = BMC(server=args.server)
    s.create_dump()
    
def do_get_dump(args):
    s = BMC(server=args.server)
    s.get_dump(args.dump)

def do_clear_dump(args):
    s = BMC(server=args.server)
    s.clear_dump(args.dump)

def do_get_esel(args):
    s = BMC(server=args.server)
    e = s.get_event(args.event)
    if e['Message'] != 'org.open_power.Error.Host.Event' and\
       e['Message'] != 'org.open_power.Error.Host.Event.Event':
        raise Exception("Event is not from Host: " + e['Message'])
    for d in e['AdditionalData']:
        data = d.split("=")
        tag = data.pop(0)
        if tag != 'ESEL':
            continue
        data = "=".join(data)
        if args.binary:
            data = data.split(" ")
            if '' == data[-1]:
                data.pop()
            data = "".join(map(lambda x: chr(int(x, 16)), data))
        print(data)


parser = argparse.ArgumentParser()
parser.add_argument('--server', help='hostname or IP of BMC', type=str,
                    required=True)

subparsers = parser.add_subparsers()

list_events = subparsers.add_parser('list', help='List all events on BMC')
list_events.set_defaults(func=do_list_events)

view_event = subparsers.add_parser(
    'view', help='View all data for an individual event')
view_event.add_argument('event', help='The event to view')
view_event.set_defaults(func=do_view_event)

get_esel = subparsers.add_parser(
    'get-esel', help='Extract OpenPOWER eSEL data for an individual event')
get_esel.add_argument('event', help='The event to get eSEL from')
get_esel.add_argument('--binary', help='Print event in raw binary',
                      action='store_const', const=True)
get_esel.set_defaults(func=do_get_esel)

clear_event = subparsers.add_parser(
    'clear', help="Clear individual event")
clear_event.add_argument('event', help="The event to clear")
clear_event.set_defaults(func=do_clear_event)

list_dumps = subparsers.add_parser(
    'list-dumps', help="List all dumps")
list_dumps.set_defaults(func=do_list_dumps)

create_dump = subparsers.add_parser(
    'create-dump', help="Create a dump")
create_dump.set_defaults(func=do_create_dump)

get_dump = subparsers.add_parser(
    'get-dump', help="Get a dump")
get_dump.add_argument('dump', help="The dump to get")
get_dump.set_defaults(func=do_get_dump)

clear_dump = subparsers.add_parser(
    'clear-dump', help="Clear individual dump")
clear_dump.add_argument('dump', help="The dump to clear")
clear_dump.set_defaults(func=do_clear_dump)

args = parser.parse_args()

if 'func' in args:
    args.func(args)
else:
    parser.print_help()
