#!/usr/bin/env python

import os
import sys
import dbus
import dbus.exceptions
import json
import logging
from xml.etree import ElementTree
from rocket import Rocket
from bottle import Bottle, abort, request, response, JSONPlugin, HTTPError
import OpenBMCMapper
from OpenBMCMapper import Mapper, PathTree, IntrospectionNodeParser, ListMatch
import spwd
import grp
import crypt

DBUS_UNKNOWN_INTERFACE = 'org.freedesktop.UnknownInterface'
DBUS_UNKNOWN_METHOD = 'org.freedesktop.DBus.Error.UnknownMethod'
DBUS_INVALID_ARGS = 'org.freedesktop.DBus.Error.InvalidArgs'
DBUS_TYPE_ERROR = 'org.freedesktop.DBus.Python.TypeError'
DELETE_IFACE = 'org.openbmc.Object.Delete'

_4034_msg = "The specified %s cannot be %s: '%s'"


def valid_user(session, *a, **kw):
    ''' Authorization plugin callback that checks
    that the user is logged in. '''
    if session is None:
        abort(403, 'Login required')


class UserInGroup:
    ''' Authorization plugin callback that checks that the user is logged in
    and a member of a group. '''
    def __init__(self, group):
        self.group = group

    def __call__(self, session, *a, **kw):
        valid_user(session, *a, **kw)
        res = False

        try:
            res = session['user'] in grp.getgrnam(self.group)[3]
        except KeyError:
            pass

        if not res:
            abort(403, 'Insufficient access')


def find_case_insensitive(value, lst):
    return next((x for x in lst if x.lower() == value.lower()), None)


def makelist(data):
    if isinstance(data, list):
        return data
    elif data:
        return [data]
    else:
        return []


class RouteHandler(object):
    _require_auth = makelist(valid_user)

    def __init__(self, app, bus, verbs, rules):
        self.app = app
        self.bus = bus
        self.mapper = Mapper(bus)
        self._verbs = makelist(verbs)
        self._rules = rules

    def _setup(self, **kw):
        request.route_data = {}
        if request.method in self._verbs:
            return self.setup(**kw)
        else:
            self.find(**kw)
            raise HTTPError(
                405, "Method not allowed.", Allow=','.join(self._verbs))

    def __call__(self, **kw):
        return getattr(self, 'do_' + request.method.lower())(**kw)

    def install(self):
        self.app.route(
            self._rules, callback=self,
            method=['GET', 'PUT', 'PATCH', 'POST', 'DELETE'])

    @staticmethod
    def try_mapper_call(f, callback=None, **kw):
        try:
            return f(**kw)
        except dbus.exceptions.DBusException, e:
            if e.get_dbus_name() != OpenBMCMapper.MAPPER_NOT_FOUND:
                raise
            if callback is None:
                def callback(e, **kw):
                    abort(404, str(e))

            callback(e, **kw)

    @staticmethod
    def try_properties_interface(f, *a):
        try:
            return f(*a)
        except dbus.exceptions.DBusException, e:
            if DBUS_UNKNOWN_INTERFACE in e.get_dbus_message():
                # interface doesn't have any properties
                return None
            if DBUS_UNKNOWN_METHOD == e.get_dbus_name():
                # properties interface not implemented at all
                return None
            raise


class DirectoryHandler(RouteHandler):
    verbs = 'GET'
    rules = '<path:path>/'

    def __init__(self, app, bus):
        super(DirectoryHandler, self).__init__(
            app, bus, self.verbs, self.rules)

    def find(self, path='/'):
        return self.try_mapper_call(
            self.mapper.get_subtree_paths, path=path, depth=1)

    def setup(self, path='/'):
        request.route_data['map'] = self.find(path)

    def do_get(self, path='/'):
        return request.route_data['map']


class ListNamesHandler(RouteHandler):
    verbs = 'GET'
    rules = ['/list', '<path:path>/list']

    def __init__(self, app, bus):
        super(ListNamesHandler, self).__init__(
            app, bus, self.verbs, self.rules)

    def find(self, path='/'):
        return self.try_mapper_call(
            self.mapper.get_subtree, path=path).keys()

    def setup(self, path='/'):
        request.route_data['map'] = self.find(path)

    def do_get(self, path='/'):
        return request.route_data['map']


class ListHandler(RouteHandler):
    verbs = 'GET'
    rules = ['/enumerate', '<path:path>/enumerate']

    def __init__(self, app, bus):
        super(ListHandler, self).__init__(
            app, bus, self.verbs, self.rules)

    def find(self, path='/'):
        return self.try_mapper_call(
            self.mapper.get_subtree, path=path)

    def setup(self, path='/'):
        request.route_data['map'] = self.find(path)

    def do_get(self, path='/'):
        objs = {}
        mapper_data = request.route_data['map']
        tree = PathTree()
        for x, y in mapper_data.iteritems():
            tree[x] = y

        try:
            # Check to see if the root path implements
            # enumerate in addition to any sub tree
            # objects.
            root = self.try_mapper_call(
                self.mapper.get_object, path=path)
            mapper_data[path] = root
        except:
            pass

        have_enumerate = [
            (x[0], self.enumerate_capable(*x))
            for x in mapper_data.iteritems() if self.enumerate_capable(*x)]

        for x, y in have_enumerate:
            objs.update(self.call_enumerate(x, y))
            tmp = tree[x]
            # remove the subtree
            del tree[x]
            # add the new leaf back since enumerate results don't
            # include the object enumerate is being invoked on
            tree[x] = tmp

        # make dbus calls for any remaining objects
        for x, y in tree.dataitems():
            objs[x] = self.app.instance_handler.do_get(x)

        return objs

    @staticmethod
    def enumerate_capable(path, bus_data):
        busses = []
        for name, ifaces in bus_data.iteritems():
            if OpenBMCMapper.ENUMERATE_IFACE in ifaces:
                busses.append(name)
        return busses

    def call_enumerate(self, path, busses):
        objs = {}
        for b in busses:
            obj = self.bus.get_object(b, path, introspect=False)
            iface = dbus.Interface(obj, OpenBMCMapper.ENUMERATE_IFACE)
            objs.update(iface.enumerate())
        return objs


class MethodHandler(RouteHandler):
    verbs = 'POST'
    rules = '<path:path>/action/<method>'
    request_type = list

    def __init__(self, app, bus):
        super(MethodHandler, self).__init__(
            app, bus, self.verbs, self.rules)

    def find(self, path, method):
        busses = self.try_mapper_call(
            self.mapper.get_object, path=path)
        for items in busses.iteritems():
            m = self.find_method_on_bus(path, method, *items)
            if m:
                return m

        abort(404, _4034_msg % ('method', 'found', method))

    def setup(self, path, method):
        request.route_data['method'] = self.find(path, method)

    def do_post(self, path, method):
        try:
            if request.parameter_list:
                return request.route_data['method'](*request.parameter_list)
            else:
                return request.route_data['method']()

        except dbus.exceptions.DBusException, e:
            if e.get_dbus_name() == DBUS_INVALID_ARGS:
                abort(400, str(e))
            if e.get_dbus_name() == DBUS_TYPE_ERROR:
                abort(400, str(e))
            raise

    @staticmethod
    def find_method_in_interface(method, obj, interface, methods):
        if methods is None:
            return None

        method = find_case_insensitive(method, methods.keys())
        if method is not None:
            iface = dbus.Interface(obj, interface)
            return iface.get_dbus_method(method)

    def find_method_on_bus(self, path, method, bus, interfaces):
        obj = self.bus.get_object(bus, path, introspect=False)
        iface = dbus.Interface(obj, dbus.INTROSPECTABLE_IFACE)
        data = iface.Introspect()
        parser = IntrospectionNodeParser(
            ElementTree.fromstring(data),
            intf_match=ListMatch(interfaces))
        for x, y in parser.get_interfaces().iteritems():
            m = self.find_method_in_interface(
                method, obj, x, y.get('method'))
            if m:
                return m


class PropertyHandler(RouteHandler):
    verbs = ['PUT', 'GET']
    rules = '<path:path>/attr/<prop>'

    def __init__(self, app, bus):
        super(PropertyHandler, self).__init__(
            app, bus, self.verbs, self.rules)

    def find(self, path, prop):
        self.app.instance_handler.setup(path)
        obj = self.app.instance_handler.do_get(path)
        try:
            obj[prop]
        except KeyError, e:
            if request.method == 'PUT':
                abort(403, _4034_msg % ('property', 'created', str(e)))
            else:
                abort(404, _4034_msg % ('property', 'found', str(e)))

        return {path: obj}

    def setup(self, path, prop):
        request.route_data['obj'] = self.find(path, prop)

    def do_get(self, path, prop):
        return request.route_data['obj'][path][prop]

    def do_put(self, path, prop, value=None):
        if value is None:
            value = request.parameter_list

        prop, iface, properties_iface = self.get_host_interface(
            path, prop, request.route_data['map'][path])
        try:
            properties_iface.Set(iface, prop, value)
        except ValueError, e:
            abort(400, str(e))
        except dbus.exceptions.DBusException, e:
            if e.get_dbus_name() == DBUS_INVALID_ARGS:
                abort(403, str(e))
            raise

    def get_host_interface(self, path, prop, bus_info):
        for bus, interfaces in bus_info.iteritems():
            obj = self.bus.get_object(bus, path, introspect=True)
            properties_iface = dbus.Interface(
                obj, dbus_interface=dbus.PROPERTIES_IFACE)

            info = self.get_host_interface_on_bus(
                path, prop, properties_iface, bus, interfaces)
            if info is not None:
                prop, iface = info
                return prop, iface, properties_iface

    def get_host_interface_on_bus(self, path, prop, iface, bus, interfaces):
        for i in interfaces:
            properties = self.try_properties_interface(iface.GetAll, i)
            if properties is None:
                continue
            prop = find_case_insensitive(prop, properties.keys())
            if prop is None:
                continue
            return prop, i


class SchemaHandler(RouteHandler):
    verbs = ['GET']
    rules = '<path:path>/schema'

    def __init__(self, app, bus):
        super(SchemaHandler, self).__init__(
            app, bus, self.verbs, self.rules)

    def find(self, path):
        return self.try_mapper_call(
            self.mapper.get_object,
            path=path)

    def setup(self, path):
        request.route_data['map'] = self.find(path)

    def do_get(self, path):
        schema = {}
        for x in request.route_data['map'].iterkeys():
            obj = self.bus.get_object(x, path, introspect=False)
            iface = dbus.Interface(obj, dbus.INTROSPECTABLE_IFACE)
            data = iface.Introspect()
            parser = IntrospectionNodeParser(
                ElementTree.fromstring(data))
            for x, y in parser.get_interfaces().iteritems():
                schema[x] = y

        return schema


class InstanceHandler(RouteHandler):
    verbs = ['GET', 'PUT', 'DELETE']
    rules = '<path:path>'
    request_type = dict

    def __init__(self, app, bus):
        super(InstanceHandler, self).__init__(
            app, bus, self.verbs, self.rules)

    def find(self, path, callback=None):
        return {path: self.try_mapper_call(
            self.mapper.get_object,
            callback,
            path=path)}

    def setup(self, path):
        callback = None
        if request.method == 'PUT':
            def callback(e, **kw):
                abort(403, _4034_msg % ('resource', 'created', path))

        if request.route_data.get('map') is None:
            request.route_data['map'] = self.find(path, callback)

    def do_get(self, path):
        properties = {}
        for item in request.route_data['map'][path].iteritems():
            properties.update(self.get_properties_on_bus(
                path, *item))

        return properties

    @staticmethod
    def get_properties_on_iface(properties_iface, iface):
        properties = InstanceHandler.try_properties_interface(
            properties_iface.GetAll, iface)
        if properties is None:
            return {}
        return properties

    def get_properties_on_bus(self, path, bus, interfaces):
        properties = {}
        obj = self.bus.get_object(bus, path, introspect=False)
        properties_iface = dbus.Interface(
            obj, dbus_interface=dbus.PROPERTIES_IFACE)
        for i in interfaces:
            properties.update(self.get_properties_on_iface(
                properties_iface, i))

        return properties

    def do_put(self, path):
        # make sure all properties exist in the request
        obj = set(self.do_get(path).keys())
        req = set(request.parameter_list.keys())

        diff = list(obj.difference(req))
        if diff:
            abort(403, _4034_msg % (
                'resource', 'removed', '%s/attr/%s' % (path, diff[0])))

        diff = list(req.difference(obj))
        if diff:
            abort(403, _4034_msg % (
                'resource', 'created', '%s/attr/%s' % (path, diff[0])))

        for p, v in request.parameter_list.iteritems():
            self.app.property_handler.do_put(
                path, p, v)

    def do_delete(self, path):
        for bus_info in request.route_data['map'][path].iteritems():
            if self.bus_missing_delete(path, *bus_info):
                abort(403, _4034_msg % ('resource', 'removed', path))

        for bus in request.route_data['map'][path].iterkeys():
            self.delete_on_bus(path, bus)

    def bus_missing_delete(self, path, bus, interfaces):
        return DELETE_IFACE not in interfaces

    def delete_on_bus(self, path, bus):
        obj = self.bus.get_object(bus, path, introspect=False)
        delete_iface = dbus.Interface(
            obj, dbus_interface=DELETE_IFACE)
        delete_iface.Delete()


class SessionHandler(MethodHandler):
    ''' Handles the /login and /logout routes, manages
    server side session store and session cookies.  '''

    rules = ['/login', '/logout']
    login_str = "User '%s' logged %s"
    bad_passwd_str = "Invalid username or password"
    no_user_str = "No user logged in"
    bad_json_str = "Expecting request format { 'data': " \
        "[<username>, <password>] }, got '%s'"
    _require_auth = None
    MAX_SESSIONS = 16

    def __init__(self, app, bus):
        super(SessionHandler, self).__init__(
            app, bus)
        self.hmac_key = os.urandom(128)
        self.session_store = []

    @staticmethod
    def authenticate(username, clear):
        try:
            encoded = spwd.getspnam(username)[1]
            return encoded == crypt.crypt(clear, encoded)
        except KeyError:
            return False

    def invalidate_session(self, session):
        try:
            self.session_store.remove(session)
        except ValueError:
            pass

    def new_session(self):
        sid = os.urandom(32)
        if self.MAX_SESSIONS <= len(self.session_store):
            self.session_store.pop()
        self.session_store.insert(0, {'sid': sid})

        return self.session_store[0]

    def get_session(self, sid):
        sids = [x['sid'] for x in self.session_store]
        try:
            return self.session_store[sids.index(sid)]
        except ValueError:
            return None

    def get_session_from_cookie(self):
        return self.get_session(
            request.get_cookie(
                'sid', secret=self.hmac_key))

    def do_post(self, **kw):
        if request.path == '/login':
            return self.do_login(**kw)
        else:
            return self.do_logout(**kw)

    def do_logout(self, **kw):
        session = self.get_session_from_cookie()
        if session is not None:
            user = session['user']
            self.invalidate_session(session)
            response.delete_cookie('sid')
            return self.login_str % (user, 'out')

        return self.no_user_str

    def do_login(self, **kw):
        session = self.get_session_from_cookie()
        if session is not None:
            return self.login_str % (session['user'], 'in')

        if len(request.parameter_list) != 2:
            abort(400, self.bad_json_str % (request.json))

        if not self.authenticate(*request.parameter_list):
            return self.bad_passwd_str

        user = request.parameter_list[0]
        session = self.new_session()
        session['user'] = user
        response.set_cookie(
            'sid', session['sid'], secret=self.hmac_key,
            secure=True,
            httponly=True)
        return self.login_str % (user, 'in')

    def find(self, **kw):
        pass

    def setup(self, **kw):
        pass


class AuthorizationPlugin(object):
    ''' Invokes an optional list of authorization callbacks. '''

    name = 'authorization'
    api = 2

    class Compose:
        def __init__(self, validators, callback, session_mgr):
            self.validators = validators
            self.callback = callback
            self.session_mgr = session_mgr

        def __call__(self, *a, **kw):
            sid = request.get_cookie('sid', secret=self.session_mgr.hmac_key)
            session = self.session_mgr.get_session(sid)
            for x in self.validators:
                x(session, *a, **kw)

            return self.callback(*a, **kw)

    def apply(self, callback, route):
        undecorated = route.get_undecorated_callback()
        if not isinstance(undecorated, RouteHandler):
            return callback

        auth_types = getattr(
            undecorated, '_require_auth', None)
        if not auth_types:
            return callback

        return self.Compose(
            auth_types, callback, undecorated.app.session_handler)


class JsonApiRequestPlugin(object):
    ''' Ensures request content satisfies the OpenBMC json api format. '''
    name = 'json_api_request'
    api = 2

    error_str = "Expecting request format { 'data': <value> }, got '%s'"
    type_error_str = "Unsupported Content-Type: '%s'"
    json_type = "application/json"
    request_methods = ['PUT', 'POST', 'PATCH']

    @staticmethod
    def content_expected():
        return request.method in JsonApiRequestPlugin.request_methods

    def validate_request(self):
        if request.content_length > 0 and \
                request.content_type != self.json_type:
            abort(415, self.type_error_str % request.content_type)

        try:
            request.parameter_list = request.json.get('data')
        except ValueError, e:
            abort(400, str(e))
        except (AttributeError, KeyError, TypeError):
            abort(400, self.error_str % request.json)

    def apply(self, callback, route):
        verbs = getattr(
            route.get_undecorated_callback(), '_verbs', None)
        if verbs is None:
            return callback

        if not set(self.request_methods).intersection(verbs):
            return callback

        def wrap(*a, **kw):
            if self.content_expected():
                self.validate_request()
            return callback(*a, **kw)

        return wrap


class JsonApiRequestTypePlugin(object):
    ''' Ensures request content type satisfies the OpenBMC json api format. '''
    name = 'json_api_method_request'
    api = 2

    error_str = "Expecting request format { 'data': %s }, got '%s'"

    def apply(self, callback, route):
        request_type = getattr(
            route.get_undecorated_callback(), 'request_type', None)
        if request_type is None:
            return callback

        def validate_request():
            if not isinstance(request.parameter_list, request_type):
                abort(400, self.error_str % (str(request_type), request.json))

        def wrap(*a, **kw):
            if JsonApiRequestPlugin.content_expected():
                validate_request()
            return callback(*a, **kw)

        return wrap


class JsonApiResponsePlugin(object):
    ''' Emits normal responses in the OpenBMC json api format. '''
    name = 'json_api_response'
    api = 2

    def apply(self, callback, route):
        def wrap(*a, **kw):
            resp = {'data': callback(*a, **kw)}
            resp['status'] = 'ok'
            resp['message'] = response.status_line
            return resp
        return wrap


class JsonApiErrorsPlugin(object):
    ''' Emits error responses in the OpenBMC json api format. '''
    name = 'json_api_errors'
    api = 2

    def __init__(self, **kw):
        self.app = None
        self.function_type = None
        self.original = None
        self.json_opts = {
            x: y for x, y in kw.iteritems()
            if x in ['indent', 'sort_keys']}

    def setup(self, app):
        self.app = app
        self.function_type = type(app.default_error_handler)
        self.original = app.default_error_handler
        self.app.default_error_handler = self.function_type(
            self.json_errors, app, Bottle)

    def apply(self, callback, route):
        return callback

    def close(self):
        self.app.default_error_handler = self.function_type(
            self.original, self.app, Bottle)

    def json_errors(self, res, error):
        response_object = {'status': 'error', 'data': {}}
        response_object['message'] = error.status_line
        response_object['data']['description'] = str(error.body)
        if error.status_code == 500:
            response_object['data']['exception'] = repr(error.exception)
            response_object['data']['traceback'] = error.traceback.splitlines()

        json_response = json.dumps(response_object, **self.json_opts)
        response.content_type = 'application/json'
        return json_response


class RestApp(Bottle):
    def __init__(self, bus):
        super(RestApp, self).__init__(autojson=False)
        self.bus = bus
        self.mapper = Mapper(bus)

        self.install_hooks()
        self.install_plugins()
        self.create_handlers()
        self.install_handlers()

    def install_plugins(self):
        # install json api plugins
        json_kw = {'indent': 2, 'sort_keys': True}
        self.install(JSONPlugin(**json_kw))
        self.install(JsonApiErrorsPlugin(**json_kw))
        self.install(AuthorizationPlugin())
        self.install(JsonApiResponsePlugin())
        self.install(JsonApiRequestPlugin())
        self.install(JsonApiRequestTypePlugin())

    def install_hooks(self):
        self.real_router_match = self.router.match
        self.router.match = self.custom_router_match
        self.add_hook('before_request', self.strip_extra_slashes)

    def create_handlers(self):
        # create route handlers
        self.session_handler = SessionHandler(self, self.bus)
        self.directory_handler = DirectoryHandler(self, self.bus)
        self.list_names_handler = ListNamesHandler(self, self.bus)
        self.list_handler = ListHandler(self, self.bus)
        self.method_handler = MethodHandler(self, self.bus)
        self.property_handler = PropertyHandler(self, self.bus)
        self.schema_handler = SchemaHandler(self, self.bus)
        self.instance_handler = InstanceHandler(self, self.bus)

    def install_handlers(self):
        self.session_handler.install()
        self.directory_handler.install()
        self.list_names_handler.install()
        self.list_handler.install()
        self.method_handler.install()
        self.property_handler.install()
        self.schema_handler.install()
        # this has to come last, since it matches everything
        self.instance_handler.install()

    def custom_router_match(self, environ):
        ''' The built-in Bottle algorithm for figuring out if a 404 or 405 is
            needed doesn't work for us since the instance rules match
            everything. This monkey-patch lets the route handler figure
            out which response is needed.  This could be accomplished
            with a hook but that would require calling the router match
            function twice.
        '''
        route, args = self.real_router_match(environ)
        if isinstance(route.callback, RouteHandler):
            route.callback._setup(**args)

        return route, args

    @staticmethod
    def strip_extra_slashes():
        path = request.environ['PATH_INFO']
        trailing = ("", "/")[path[-1] == '/']
        parts = filter(bool, path.split('/'))
        request.environ['PATH_INFO'] = '/' + '/'.join(parts) + trailing

if __name__ == '__main__':
    log = logging.getLogger('Rocket.Errors')
    log.setLevel(logging.INFO)
    log.addHandler(logging.StreamHandler(sys.stdout))

    bus = dbus.SystemBus()
    app = RestApp(bus)
    default_cert = os.path.join(
        sys.prefix, 'share', os.path.basename(__file__), 'cert.pem')

    server = Rocket(
        ('0.0.0.0', 443, default_cert, default_cert),
        'wsgi', {'wsgi_app': app},
        min_threads=1,
        max_threads=1)
    server.start()
