#!/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
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.GetTree(
				self.path, 0, 'exact')[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.GetTree(path, 0, 'exact')[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.GetTreePaths(self.path, 1, 'exact')
		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.GetTree(self.path, -1, 'fuzzy')
		if self.path in objs:
			del objs[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 do_GET(self):
		objs = {}
		mapper_data = self.mapper.GetTree(self.path, -1, 'fuzzy')
		if self.path in mapper_data:
			del mapper_data[self.path]

		for x,y in mapper_data.iteritems():
			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.parts[-2] == 'attr':
			return AttrHandler(self, path.fq(last = -2), data)

		if 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.GetTree(
				path.fq(), 0, 'exact')
		if mapper_entry:
			return InstanceHandler(self, path.fq(), data, 
					mapper_entry[path.fq()])

		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):
		BaseHTTPServer.HTTPServer.__init__(self, bind, handler)
		self.bus = dbus.SystemBus()
		mapper = self.bus.get_object(OpenBMCMapper.MAPPER_NAME,
				OpenBMCMapper.MAPPER_PATH)
		self.mapper = dbus.Interface(mapper,
				dbus_interface = OpenBMCMapper.MAPPER_IFACE)

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