#! /usr/bin/python
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#

#
# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
#

# Copyright 2010, Richard Lowe

#
# Various database lookup classes/methods, i.e.:
#     * monaco
#     * bugs.opensolaris.org (b.o.o.)
#     * redmine (illumos.org)
#

import htmllib
import re
import urllib
import urllib2

try:				# Python >= 2.5
	from xml.etree import ElementTree
except ImportError:
	from elementtree import ElementTree

class NonExistentBug(Exception):
	def __str__(self):
		return "Bug %s does not exist" % (Exception.__str__(self))

class BugDBException(Exception):
	def __str__(self):
		return "Unknown bug database: %s" % (Exception.__str__(self))

class BugDB(object):
	"""Lookup change requests.

	Usage:
	bdb = BugDB()
	r = bdb.lookup("6455550")
	print r["6455550"]["synopsis"]
	r = bdb.lookup(["6455550", "6505625"])
	print r["6505625"]["synopsis"]
	"""

	VALID_DBS = ["illumos"]

	def __init__(self, priority = ["illumos"]):
		"""Create a BugDB object.

		Keyword argument:
		priority: use bug databases in this order
		"""
		for database in priority:
			if database not in self.VALID_DBS:
				raise BugDBException, database
		self.__priority = priority


	def __illbug(self, cr):
		url = "http://illumos.org/issues/%s.xml" % cr
		req = urllib2.Request(url)

		try:
			data = urllib2.urlopen(req)
		except urllib2.HTTPError, e:
			if e.code == 404:
				raise NonExistentBug(cr)
			else:
				raise

		bug = ElementTree.parse(data)

		return {'cr_number': bug.find('id').text,
			'synopsis': bug.find('subject').text,
			'status': bug.find('status').attrib['name']
		}


	def lookup(self, crs):
		"""Return all info for requested change reports.

		Argument:
		crs: one change request id (may be integer, string, or list),
		     or multiple change request ids (must be a list)

		Returns:
		Dictionary, mapping CR=>dictionary, where the nested dictionary
		is a mapping of field=>value
		"""
		results = {}
		if not isinstance(crs, list):
			crs = [str(crs)]
		for database in self.__priority:
			if database == "illumos":
				for cr in crs:
					try:
						results[str(cr)] = self.__illbug(cr)
					except NonExistentBug:
						continue

			# the CR has already been found by one bug database
			# so don't bother looking it up in the others
			for cr in crs:
				if cr in results:
					crs.remove(cr)

		return results