#!/usr/bin/env python

# Contributors Listed Below - COPYRIGHT 2015
# [+] International Business Machines Corp.
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied. See the License for the specific language governing
# permissions and limitations under the License.

import BaseHTTPServer
import SocketServer
import json
import dbus
from OpenBMCMapper import Path, Mapper, PathTree
import OpenBMCMapper

class RestException(Exception):
	def __init__(self, msg, http_status=403):
		self.status = http_status
		super(RestException, self).__init__(msg)

class Response(object):
	def render(self, handler):
		raise NotImplemented()

class ErrorResponse(Response):
	def __init__(self, ex):
		self.ex = ex

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

class JSONResponse(Response):
	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 RequestHandler(object):
	def __init__(self, req, path, data):
		self.req = req
		self.path = path
		self.bus = req.server.bus
		self.mapper = req.server.mapper
		self.data = data

	def do_command(self):
		f = getattr(self, 'do_' + self.req.command)
		return f()

	def do_GET(self):
		raise RestException("Not Implemented", 501)

	def do_PUT(self):
		raise RestException("Not Implemented", 501)

	def do_POST(self):
		raise RestException("Not Implemented", 501)

	def do_PATCH(self):
		raise RestException("Not Implemented", 501)

	def do_DELETE(self):
		raise RestException("Not Implemented", 501)

class MethodHandler(RequestHandler):
	def __init__(self, req, path, data):
		super(MethodHandler, self).__init__(req, path, data)
		self.method = Path(self.req.path).rel(first = -1)

	def find_method_in_interface(self, obj, interface):
		try:
			iface = dbus.Interface(obj, interface)
			return getattr(iface, self.method)
		except dbus.DBusException:
			return None

	def find_method_on_bus(self, bus, interfaces):
		obj = self.bus.get_object(bus, self.path)
		for i in interfaces:
			m = self.find_method_in_interface(obj, i)
			if not m:
				continue
		return m

	def find_method(self):
		busses = self.mapper.get_object(
				self.path)
		for items in busses.iteritems():
			m = self.find_method_on_bus(*items)
			if not m:
				continue

		return m

	def do_POST(self):
		try:
			method = self.find_method()
		except:
			raise RestException("Not Found", 404)
		try:
			d = { 'result': method(*self.data),
					'status': 'OK'}
		except Exception, e:
			d = { 'error': str(e),
					'status': 'error'}
		return d

class InstanceHandler(RequestHandler):
	def __init__(self, req, path, data, busses):
		super(InstanceHandler, self).__init__(req, path, data)
		self.busses = busses

	def get_one_iface(self, properties_iface, iface):
		try:
			return properties_iface.GetAll(iface)
		except:
			# interface doesn't have any properties
			return {}

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

		return properties

	def do_GET(self):
		properties = {}
		for item in self.busses.iteritems():
			properties.update(self.get_one_bus(*item))

		return properties

	def try_set_one_interface(self, prop, value, properties_iface, interface):
		try:
			properties_iface.Set(interface, prop, value)
			return True
		except:
			# property doesn't live on this interface/bus
			return False

	def try_set_one_bus(self, prop, value, bus, interfaces):
		obj = self.bus.get_object(bus, self.path)
		properties_iface = dbus.Interface(
				obj, dbus_interface=dbus.PROPERTIES_IFACE)

		for iface in interfaces:
			if self.try_set_one_interface(prop, value,
					properties_iface, iface):
				return True

		return False

	def set_one_property(self, prop, value):
		for item in self.busses.iteritems():
			if not self.try_set_one_bus(prop, value, *item):
				raise RestException("Not Found", 404)

	def validate_json(self):
		if type(self.data) != dict:
			raise RestException("Bad Request", 400)

		obj = self.do_GET()
		if len(self.data) != len(obj):
			raise RestException("Bad Request", 400)
		for x in obj.iterkeys():
			if x not in self.data:
				raise RestException("Bad Request", 400)

	def do_PUT(self):
		try:
			self.validate_json()
			for p in self.data.iteritems():
				self.set_one_property(*p)

			d = { 'status': 'OK'}
		except Exception, e:
			d = { 'error': str(e),
					'status': 'error'}
		return d

	def do_POST(self):
		for p in self.data.iteritems():
			self.set_one_property(*p)

class AttrHandler(RequestHandler):
	def __init__(self, req, path, data):
		super(AttrHandler, self).__init__(req, path, data)
		try:
			self.inst = InstanceHandler(req, path, data,
					self.mapper.get_object(path))
		except KeyError:
			raise RestException("Not Found", 404)
		self.attr = Path(self.req.path).rel(first = -1)

	def do_GET(self):
		obj = self.inst.do_GET()
		try:
			return obj[self.attr]
		except KeyError:
			raise RestException("Not Found", 404)

	def do_PUT(self):
		self.inst.set_one_property(self.attr, self.data)

class TypesHandler(RequestHandler):
	def __init__(self, req, path, data):
		super(TypesHandler, self).__init__(req, path, data)

	def do_GET(self):
		types = self.mapper.get_subtree_paths(self.path, 1)
		if not types:
			raise RestException("Not Found", 404)

		return types

class ListHandler(RequestHandler):
	def __init__(self, req, path, data):
		super(ListHandler, self).__init__(req, path, data)

	def do_GET(self):
		objs = self.mapper.get_subtree(self.path)
		if not objs:
			raise RestException("Not Found", 404)

		return objs.keys()

class EnumerateHandler(RequestHandler):
	def __init__(self, req, path, data):
		super(EnumerateHandler, self).__init__(req, path, data)

	def get_enumerate(self, path, data):
		busses = []
		for s, i in data.iteritems():
			if OpenBMCMapper.ENUMERATE_IFACE in i:
				busses.append(s)
		return busses

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

	def do_GET(self):
		objs = {}
		mapper_data = self.mapper.get_subtree(self.path)
		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.mapper.get_object(self.path)
			mapper_data[self.path] = root
		except:
			pass

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

		for x,y in have_enumerate:
			objs.update(self.call_enumerate(x, y))
			tmp = tree[x]
			del tree[x]
			tree[x] = tmp

		for x,y in tree.dataitems():
			objs[x] = InstanceHandler(self.req, x, self.data, y).do_GET()

		if not objs:
			raise RestException("Not Found", 404)

		return objs

class DBusRestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
	def get_real_handler(self, data):
		path = Path(self.path)

		if self.path[-1] == '/':
			return TypesHandler(self, path.fq(), data)

		if path.parts[-1] == 'list':
			return ListHandler(self, path.fq(last = -1), data)

		if path.parts[-1] == 'enumerate':
			return EnumerateHandler(self, path.fq(last = -1), data)

		if path.depth() > 1 and path.parts[-2] == 'attr':
			return AttrHandler(self, path.fq(last = -2), data)

		if path.depth() > 1 and path.parts[-2] == 'action':
			return MethodHandler(self, path.fq(last = -2), data)

		# have to do an objectmapper query at this point
		mapper_entry = self.server.mapper.get_object(path.fq())
		if mapper_entry:
			return InstanceHandler(self, path.fq(), data,
					mapper_entry)

		raise RestException("Not Found", 404)

	def do_command(self):
		data = None
		try:
			if self.command in ['POST', 'PUT', 'PATCH']:
       		 		length = int(self.headers.getheader(
					'content-length'))
			        data = json.loads(self.rfile.read(length))

			resp = self.get_real_handler(data).do_command()
			if not resp:
				resp = {'status': 'OK' }
			response = JSONResponse(resp)
		except RestException, ex:
			response = ErrorResponse(ex)

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

	def do_GET(self):
		return self.do_command()

	def do_POST(self):
		return self.do_command()

	def do_PATCH(self):
		return self.do_command()

	def do_PUT(self):
		return self.do_command()

	def do_DELETE(self):
		return self.do_command()

class HTTPServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
	def __init__(self, bind, handler, bus):
		BaseHTTPServer.HTTPServer.__init__(self, bind, handler)
		self.bus = bus
		self.mapper = Mapper(self.bus)

if __name__ == '__main__':
	bus = dbus.SystemBus()
	server = HTTPServer(('', 80), DBusRestHandler, bus)
	server.serve_forever()
