#    Licensed to the Apache Software Foundation (ASF) under one
#    or more contributor license agreements.  See the NOTICE file
#    distributed with this work for additional information
#    regarding copyright ownership.  The ASF licenses this file
#    to you 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.


from ctypes import *
from tempfile import NamedTemporaryFile
import weakref, sys

class FILE(Structure):
    pass

# PyFile_AsFile converts Python files into regular "FILE *" objects
PyFile_AsFile = pythonapi.PyFile_AsFile
PyFile_AsFile.argtypes = [py_object]
PyFile_AsFile.restype = POINTER(FILE)

# A friendly wrapper for exceptions
class SubversionException(Exception):
    def __init__(self, err, message=None, inherited=False):
        if isinstance(err, (int, long)):
            err = svn_error_create(err, None, message)

        self._as_parameter_ = err

        # Get a nice error message with line numbers and everything 
        f = NamedTemporaryFile()
        svn_handle_error2(err, PyFile_AsFile(f.file), 0, "")
        f.seek(0)
        self.value = f.read()
        f.close()

        # Save off the message and apr_err stuff
        self.message = err[0].message
        self.apr_err = err[0].apr_err
        self.child = None
        if err[0].child:
            self.child = SubversionException(err[0].child, None, True)

        if not inherited:
            # Cleanup the error when we die
            self.weakself = weakref.ref(self, lambda x: svn_error_clear(err))

    def __str__(self):
        return self.value

# If a error is returned from a Subversion function,
# raise an exception 
def SVN_ERR(ret):
    if ret:
        err = cast(ret, POINTER(svn_error_t))
        raise SubversionException(err)
    return ret

# If a error is returned from a Subversion function,
# raise an exception
def _svn_errcheck(result, func, args):
    return SVN_ERR(result)

# As of ctypes 1.0, ctypes does not support custom error-checking
# functions on callbacks, nor does it support custom datatypes on
# callbacks, so ctypesgen sets the return values for callbacks
# to c_void_p.
#
# Callback functions, therefore, won't have their errors checked
# automatically. Users who call these functions should wrap
# their function call using SVN_ERR so as to ensure that any
# exceptions are thrown appropriately.


###########################
