/***********************************************************
Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
The Netherlands.

                        All Rights Reserved

Permission to use, copy, modify, and distribute this software and its 
documentation for any purpose and without fee is hereby granted, 
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in 
supporting documentation, and that the names of Stichting Mathematisch
Centrum or CWI not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior permission.

STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

******************************************************************/

/* Access object implementation */

/* XXX TO DO LIST
   - __init__ and __del__ (and all other similar methods)
     should be usable even when private, not ignored
*/

#include "allobjects.h"
#include "ceval.h"
#include "structmember.h"
#include "modsupport.h"		/* For getargs() etc. */

typedef struct {
	OB_HEAD
	object		*ac_value;
	object		*ac_owner;
	typeobject	*ac_type;
	int		ac_mode;
} accessobject;

/* Forward */
static int typecheck PROTO((object *, typeobject *));
static int ownercheck PROTO((object *, object *, int, int));

object *
newaccessobject(value, owner, type, mode)
	object *value;
	object *owner;
	typeobject *type;
	int mode;
{
	accessobject *ap;
	if (!typecheck(value, type)) {
		err_setstr(AccessError,
		"access: initial value has inappropriate type");
		return NULL;
	}
	ap = NEWOBJ(accessobject, &Accesstype);
	if (ap == NULL)
		return NULL;
	XINCREF(value);
	ap->ac_value = value;
	XINCREF(owner);
	ap->ac_owner = owner;
	XINCREF(type);
	ap->ac_type = (typeobject *)type;
	ap->ac_mode = mode;
	return (object *)ap;
}

object *
cloneaccessobject(op)
	object *op;
{
	register accessobject *ap;
	if (!is_accessobject(op)) {
		err_badcall();
		return NULL;
	}
	ap = (accessobject *)op;
	return newaccessobject(ap->ac_value, ap->ac_owner,
			       ap->ac_type, ap->ac_mode);
}

void
setaccessowner(op, owner)
	object *op;
	object *owner;
{
	register accessobject *ap;
	if (!is_accessobject(op))
		return; /* XXX no error */
	ap = (accessobject *)op;
	XDECREF(ap->ac_owner);
	XINCREF(owner);
	ap->ac_owner = owner;
}

int
hasaccessvalue(op)
	object *op;
{	
	if (!is_accessobject(op))
		return 0;
	return ((accessobject *)op)->ac_value != NULL;
}

object *
getaccessvalue(op, caller)
	object *op;
	object *caller;
{
	register accessobject *ap;
	if (!is_accessobject(op)) {
		err_badcall();
		return NULL;
	}
	ap = (accessobject *)op;
	
	if (!ownercheck(caller, ap->ac_owner, AC_R, ap->ac_mode)) {
		err_setstr(AccessError, "read access denied");
		return NULL;
	}
	
	if (ap->ac_value == NULL) {
		err_setstr(AccessError, "no current value");
		return NULL;
	}
	INCREF(ap->ac_value);
	return ap->ac_value;
}

int
setaccessvalue(op, caller, value)
	object *op;
	object *caller;
	object *value;
{
	register accessobject *ap;
	if (!is_accessobject(op)) {
		err_badcall();
		return -1;
	}
	ap = (accessobject *)op;
	
	if (!ownercheck(caller, ap->ac_owner, AC_W, ap->ac_mode)) {
		err_setstr(AccessError, "write access denied");
		return -1;
	}
	
	if (!typecheck(value, ap->ac_type)) {
		err_setstr(AccessError, "assign value of inappropriate type");
		return -1;
	}
	
	if (value == NULL) { /* Delete it */
		if (ap->ac_value == NULL) {
			err_setstr(AccessError, "no current value");
			return -1;
		}
		DECREF(ap->ac_value);
		ap->ac_value = NULL;
		return 0;
	}
	XDECREF(ap->ac_value);
	INCREF(value);
	ap->ac_value = value;
	return 0;
}

static int
typecheck(value, type)
	object *value;
	typeobject *type;
{
	object *x;
	if (value == NULL || type == NULL)
		return 1; /* No check */
	if (value->ob_type == type)
		return 1; /* Exact match */
	if (type == &Anynumbertype) {
		if (value->ob_type->tp_as_number == NULL)
			return 0;
		if (!is_instanceobject(value))
			return 1;
		/* For instances, make sure it really looks like a number */
		x = getattr(value, "__sub__");
		if (x == NULL) {
			err_clear();
			return 0;
		}
		DECREF(x);
		return 1;
	}
	if (type == &Anysequencetype) {
		if (value->ob_type->tp_as_sequence == NULL)
			return 0;
		if (!is_instanceobject(value))
			return 1;
		/* For instances, make sure it really looks like a sequence */
		x = getattr(value, "__getslice__");
		if (x == NULL) {
			err_clear();
			return 0;
		}
		DECREF(x);
		return 1;
	}
	if (type == &Anymappingtype) {
		if (value->ob_type->tp_as_mapping == NULL)
			return 0;
		if (!is_instanceobject(value))
			return 1;
		/* For instances, make sure it really looks like a mapping */
		x = getattr(value, "__getitem__");
		if (x == NULL) {
			err_clear();
			return 0;
		}
		DECREF(x);
		return 1;
	}
	return 0;
}

static int
isprivileged(caller)
	object *caller;
{
	object *g;
	static char privileged[] = "__privileged__";
	if (caller != NULL && hasattr(caller, privileged))
		return 1;
	g = getglobals();
	if (g != NULL && dictlookup(g, privileged))
		return 1;
	return 0;
}

static int
ownercheck(caller, owner, access, mode)
	object *caller;
	object *owner;
	int access;
	int mode;
{
	int mask = AC_PUBLIC;
	if (caller == owner || isprivileged(caller))
		mask |= AC_PRIVATE | AC_PROTECTED;
	else if (caller != NULL && owner != NULL &&
		 is_classobject(owner) && is_classobject(caller) &&
		 (issubclass(caller, owner) ||
		  issubclass(owner, caller)))
			mask |= AC_PROTECTED;
	return access & mode & mask;
}

/* Access methods */

static void
access_dealloc(ap)
	accessobject *ap;
{
	XDECREF(ap->ac_value);
	XDECREF(ap->ac_owner);
	XDECREF(ap->ac_type);
	DEL(ap);
}

#define OFF(x) offsetof(accessobject, x)

static struct memberlist access_memberlist[] = {
	{"ac_value",	T_OBJECT,	OFF(ac_value)},
	{"ac_owner",	T_OBJECT,	OFF(ac_owner)},
	{"ac_type",	T_OBJECT,	OFF(ac_type)},
	{"ac_mode",	T_INT,		OFF(ac_mode)},
	{NULL}	/* Sentinel */
};

static object *
access_getattr(ap, name)
	accessobject *ap;
	char *name;
{
	return getmember((char *)ap, access_memberlist, name);
}

static object *
access_repr(ap)
	accessobject *ap;
{
	char buf[300];
	char buf2[20];
	char *ownername;
	typeobject *type = ap->ac_type;
	if (is_classobject(ap->ac_owner)) {
		ownername =
			getstringvalue(((classobject *)ap->ac_owner)->cl_name);
	}
	else {
		sprintf(buf2, "0x%lx", (long)ap->ac_owner);
		ownername = buf2;
	}
	sprintf(buf,
	"<access object, value 0x%lx, owner %.100s, type %.100s, mode %04o>",
		(long)(ap->ac_value),
		ownername,
		type ? type->tp_name : "-",
		ap->ac_mode);
	return newstringobject(buf);
}

typeobject Accesstype = {
	OB_HEAD_INIT(&Typetype)
	0,			/*ob_size*/
	"access",		/*tp_name*/
	sizeof(accessobject),	/*tp_size*/
	0,			/*tp_itemsize*/
	/* methods */
	(destructor)access_dealloc, /*tp_dealloc*/
	0,			/*tp_print*/
	(getattrfunc)access_getattr, /*tp_getattr*/
	0,			/*tp_setattr*/
	0,			/*tp_compare*/
	(reprfunc)access_repr, /*tp_repr*/
	0,			/*tp_as_number*/
	0,			/*tp_as_sequence*/
	0,			/*tp_as_mapping*/
	0,			/*tp_hash*/
};


/* Pseudo type objects to indicate collections of types */

/* XXX This should be replaced by a more general "subclassing"
   XXX mechanism for type objects... */

typeobject Anynumbertype = {
	OB_HEAD_INIT(&Typetype)
	0,			/*ob_size*/
	"*number*",		/*tp_name*/
};

/* XXX Should really distinguish mutable and immutable sequences as well */

typeobject Anysequencetype = {
	OB_HEAD_INIT(&Typetype)
	0,			/*ob_size*/
	"*sequence*",		/*tp_name*/
};

typeobject Anymappingtype = {
	OB_HEAD_INIT(&Typetype)
	0,			/*ob_size*/
	"*mapping*",		/*tp_name*/
};
