#!/usr/bin/env python3

"""This module contains custom exceptions that are raised by diaspy.
These are not described by DIASPORA* protocol as exceptions that should be
raised by API implementations but are specific to this particular implementation.

If your program should catch all exceptions raised by diaspy and
does not need to handle them specifically you can use following code:

	# this line imports all errors
	from diaspy.errors import *

	try:
		# your code...
	except DiaspyError as e:
		# your error handling code...
	finally:
		# closing code...
"""

import warnings


class DiaspyError(Exception):
	"""Base exception for all errors
	raised by diaspy.
	"""
	pass


class LoginError(DiaspyError):
	"""Exception raised when something
	bad happens while performing actions
	related to logging in.
	"""
	pass


class TokenError(DiaspyError):
	pass

class CSRFProtectionKickedIn(TokenError):
	pass


class DataError(DiaspyError):
	pass


class InvalidDataError(DataError):
	pass


class KeyMissingFromFetchedData(InvalidDataError):
	pass


class UserError(DiaspyError):
	"""Exception raised when something related to users goes wrong.
	"""
	pass


class InvalidHandleError(DiaspyError):
	"""Raised when invalid handle is found.
	"""
	pass


class SearchError(DiaspyError):
	"""Exception raised when something related to search goes wrong.
	"""
	pass


class ConversationError(DiaspyError):
	"""Exception raised when something related to conversations goes wrong.
	"""
	pass


class AspectError(DiaspyError):
	"""Exception raised when something related to aspects goes wrong.
	"""
	pass

class UserIsNotMemberOfAspect(AspectError):
	pass


class PostError(DiaspyError):
	"""Exception raised when something related to posts goes wrong.
	"""
	pass


class StreamError(DiaspyError):
	"""Exception raised when something related to streams goes wrong.
	"""
	pass


class SettingsError(DiaspyError):
	"""Exception raised when something related to settings goes wrong.
	"""
	pass

class SearchError(DiaspyError):
	"""Exception raised when something related to searching goes wrong.
	"""
	pass

class TagError(DiaspyError):
	"""Exception raised when something related to a tag goes wrong.
	"""
	pass

def react(r, message='', accepted=[200, 201, 202, 203, 204, 205, 206], exception=DiaspyError):
	"""This method tries to decide how to react
	to a response code passed to it. If it's an
	error code it will raise an exception (it will
	call `throw()` method.

	If response code is not accepted AND cannot
	be matched to any exception, generic exception
	(DiaspyError) is raised (provided that `exception`
	param was left untouched).

	By default `accepted` param contains all HTTP
	success codes.

	User can force type of exception to raise by passing
	`exception` param.

	:param r: response code
	:type r: int
	:param message: message for the exception
	:type message: str
	:param accepted: list of accepted error codes
	:type accepted: list
	:param exception: preferred exception to raise
	:type exception: valid exception type (default: DiaspyError)
	"""
	warnings.warn(DeprecationWarning)
	if r in accepted: e = None
	else: e = DiaspyError

	if e is not None: e = exception
	throw(e, message=message)


def throw(e, message=''):
	"""This function throws an error with given message.
	If None is passed as `e` throw() will not raise
	anything.

	:param e: exception to throw
	:type e: any valid exception type or None
	:param message: message for exception
	:type message: str
	"""
	warnings.warn(DeprecationWarning)
	if e is None: pass
	else: raise e(message)
