#!/usr/bin/env python

import dbus
import BaseHTTPServer
import SocketServer
import json
import os
import sys
from xml.etree import ElementTree
from OpenBMCMapper import IntrospectionParser

busses = {
    'system': dbus.SystemBus,
}


class DBusRestException(Exception):

    def __init__(self, message, code=403):
        self.code = code
        super(DBusRestException, self).__init__(message)


class DBusRestResponse(object):

    def render(self, handler):
        raise NotImplemented()


class DBusRestJSONResponse(DBusRestResponse):

    def __init__(self, data):
        self.data = data

    def render(self, handler):
        handler.send_response(200)
        handler.send_header('Content-Type', 'application/json')
        handler.end_headers()
        handler.wfile.write(json.dumps(self.data, indent=2, sort_keys=True))


class DBusRestResourceResponse(DBusRestResponse):
    mime_map = {
        'html': 'text/html',
        'js': 'text/javascript',
        'css': 'text/css',
        'png': 'image/png',
        'gif': 'image/gif',
    }
    resource_base = os.path.join(sys.prefix, 'share',
                                 os.path.basename(__file__), 'resources')

    def __init__(self, name):
        (_, ext) = os.path.splitext(name)
        self.content_type = self.mime_map.get(ext[1:],
                                              'application/octet-stream')
        try:
            self.data = open(os.path.join(self.resource_base, name)).read()
        except IOError:
            raise DBusRestException("Not Found", 404)

    def render(self, handler):
        handler.send_response(200)
        handler.send_header('Content-Type',
                            self.content_type + '; charset=utf-8')
        handler.end_headers()
        handler.wfile.write(self.data)


class DBusRestErrorResonse(DBusRestResponse):

    def __init__(self, ex):
        self.ex = ex

    def render(self, handler):
        err = {
            'status': 'error',
            'error': self.ex.message,
        }
        handler.send_response(self.ex.code)
        handler.send_header('Content-Type', 'application/json')
        handler.end_headers()
        handler.wfile.write(json.dumps(err, indent=2, sort_keys=True))


class DBusRestHandler(BaseHTTPServer.BaseHTTPRequestHandler):

    def handle_root(self):
        return DBusRestJSONResponse({
            'status': 'ok',
            'busses': [{'name': x} for x in busses.keys()],
        })

    def handle_bus(self):
        objects = self.bus.list_names()
        objects.sort()
        return DBusRestJSONResponse({
            'status': 'ok',
            'objects': [{'name': x} for x in objects],
        })

    def get_object_or_404(self, bus_name, obj_path):
        try:
            obj = self.bus.get_object(bus_name, obj_path)
        except dbus.DBusException:
            raise DBusRestException("Object Not Found", 404)
        return obj

    def handle_service(self, bus_name):
        data = IntrospectionParser(bus_name, self.bus).introspect()
        objects = [{'path': x} for x in data.iterkeys()]

        return DBusRestJSONResponse({
            'status': 'ok',
            'bus_name': bus_name,
            'objects': objects,
        })

    def handle_object(self, obj):
        iface = dbus.Interface(obj, 'org.freedesktop.DBus.Introspectable')

        interfaces = []
        tree = ElementTree.fromstring(iface.Introspect())
        for node in tree:
            if node.tag == 'interface':
                interfaces.append({'name': node.attrib['name']})

        return DBusRestJSONResponse({
            'status': 'ok',
            'bus_name': obj.requested_bus_name,
            'object_path': obj.object_path,
            'interfaces': interfaces,
        })

    def handle_interface(self, obj, interface_name):
        iface = dbus.Interface(obj, 'org.freedesktop.DBus.Introspectable')

        interface_node = None
        tree = ElementTree.fromstring(iface.Introspect())
        for node in tree:
            if (node.tag == 'interface' and
                    node.attrib['name'] == interface_name):
                interface_node = node
                break

        if interface_node is None:
            raise DBusRestException("Interface Not Found", 404)

        methods = []
        signals = []
        base_uri = ('/bus/' + self.bus_name + '/' + obj.requested_bus_name +
                    obj.object_path + '/' + interface_name)

        def parse_method(node):
            args = []
            for child in node:
                if child.tag == 'arg':
                    args.append(child.attrib)

            return {
                'name': node.attrib['name'],
                'args': args,
                'uri': '/'.join([base_uri, node.attrib['name']]),
            }

        def parse_signal(node):
            args = []
            for child in node:
                if child.tag == 'arg':
                    args.append(child.attrib)

            return {
                'name': node.attrib['name'],
                'args': args
            }

        for node in interface_node:
            if node.tag == 'method':
                methods.append(parse_method(node))
            elif node.tag == 'signal':
                signals.append(parse_signal(node))

        iface = dbus.Interface(obj, 'org.freedesktop.DBus.Properties')
        try:
            properties = iface.GetAll(interface_name)
        except dbus.DBusException:
            properties = []

        return DBusRestJSONResponse({
            'status': 'ok',
            'bus_name': obj.requested_bus_name,
            'object_path': obj.object_path,
            'interface': interface_name,
            'methods': methods,
            'signals': signals,
            'properties': properties,
        })

    def handle_property(self, obj, interface_name, property_name):
        iface = dbus.Interface(obj, 'org.freedesktop.DBus.Properties')
        try:
            value = iface.Get(interface_name, property_name)
        except dbus.DBusException:
            raise DBusRestException("Property Not Found", 404)

        return DBusRestJSONResponse({
            'status': 'ok',
            'bus_name': obj.requested_bus_name,
            'object_path': obj.object_path,
            'interface': interface_name,
            'property': property_name,
            'value': value,
        })

    def dispatch_bus(self, parts):

        if not parts:
            return self.handle_root()

        self.bus_name = parts.pop(0)
        busfn = busses.get(self.bus_name, None)
        if busfn is None:
            raise DBusRestException("Bus Not Found", 404)

        self.bus = busfn()

        if not parts:
            return self.handle_bus()

        bus_name = parts.pop(0)

        if not parts:
            return self.handle_service(bus_name)

        # construct our object path, stopping when we get to an
        # interface name
        object_path = ''
        while parts:
            if '.' in parts[0]:
                break
            object_path += '/' + parts.pop(0)

        obj = self.get_object_or_404(bus_name, object_path)

        if not parts:
            return self.handle_object(obj)

        interface_name = parts.pop(0)
        if not parts:
            return self.handle_interface(obj, interface_name)

        property_name = parts.pop(0)
        if not parts:
            return self.handle_property(obj, interface_name, property_name)

        raise DBusRestException("Not Found", 404)

    def dispatch_resource(self, parts):
        return DBusRestResourceResponse(parts[0])

    def dispatch(self):
        parts = filter(bool, self.path.split('/'))

        if parts:
            action = parts.pop(0)

            if action == 'bus':
                return self.dispatch_bus(parts)

            elif action == 'res':
                return self.dispatch_resource(parts)

            raise DBusRestException("Not Found", 404)

        return self.dispatch_resource(['index.html'])

    def handle_call(self, obj, interface_name, call_name, data):
        iface = dbus.Interface(obj, interface_name)
        call = getattr(iface, call_name)
        d = {
            'obj': obj.object_path,
            'interface': interface_name,
            'call': call_name,
        }
        try:
            d.update({
                'result': call(*data),
                'status': 'ok',
            })
        except Exception, e:
            d.update({
                'error': str(e),
                'status': 'error',
            })
        return DBusRestJSONResponse(d)

    def dispatch_call(self, data):
        parts = filter(bool, self.path.split('/'))
        if not parts:
            raise DBusRestException("Not Found", 404)

        action = parts.pop(0)
        if action != 'bus':
            raise DBusRestException("Not Found", 404)

        busfn = busses.get(parts.pop(0), None)
        if busfn is None:
            raise DBusRestException("Bus Not Found", 404)

        self.bus = busfn()

        if not parts:
            raise DBusRestException("Not Found", 404)

        bus_name = parts.pop(0)

        if not parts:
            raise DBusRestException("Not Found", 404)

        # construct our object path, stopping when we get to an
        # interface name
        object_path = ''
        while parts:
            if '.' in parts[0]:
                break
            object_path += '/' + parts.pop(0)

        obj = self.get_object_or_404(bus_name, object_path)

        if not parts:
            raise DBusRestException("Not Found", 404)

        interface_name = parts.pop(0)
        if not parts:
            raise DBusRestException("Not Found", 404)

        call_name = parts.pop(0)

        return self.handle_call(obj, interface_name, call_name, data)

    def do_GET(self):
        try:
            response = self.dispatch()
        except DBusRestException, ex:
            response = DBusRestErrorResonse(ex)

        response.render(self)
        self.wfile.close()

    def do_POST(self):
        length = int(self.headers.getheader('content-length'))
        data = json.loads(self.rfile.read(length))
        try:
            response = self.dispatch_call(data)
        except DBusRestException, ex:
            response = DBusRestErrorResonse(ex)

        response.render(self)
        self.wfile.close()


class HTTPServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
    pass

if __name__ == '__main__':
    server = HTTPServer(('', 3000), DBusRestHandler)
    server.serve_forever()
