#!/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, bus):
		BaseHTTPServer.HTTPServer.__init__(self, bind, handler)
		self.bus = bus
		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, bus)
	server.serve_forever()
