import sys
import os
sys.path.insert(0, '.')
sys.path.extend(os.environ.get('PYTHONPATH','').split(os.pathsep))
import imp
import traceback


__name__ = '__main__'
mainmodule = type(sys)('__main__')
sys.modules['__main__'] = mainmodule

import cffi

# this is a list holding object we do not want to be freed (like callback and handlers)
uwsgi_gc = []
# the main ffi
ffi = cffi.FFI()

# the hooks we need to patch
hooks = '''
void free(void *);
ssize_t read(int, void *, size_t);
ssize_t write(int, const void *, size_t);
int close(int);

void (*uwsgi_pypy_hook_execute_source)(char *);
void (*uwsgi_pypy_hook_loader)(char *);
void (*uwsgi_pypy_hook_file_loader)(char *);
void (*uwsgi_pypy_hook_paste_loader)(char *);
void (*uwsgi_pypy_hook_pythonpath)(char *);
void (*uwsgi_pypy_hook_request)(struct wsgi_request *);
void (*uwsgi_pypy_post_fork_hook)(void);
'''

# here we load CFLAGS and uwsgi.h from the binary
defines0 = '''
char *uwsgi_get_cflags();
char *uwsgi_get_dot_h();
'''
ffi.cdef(defines0)
lib0 = ffi.verify(defines0)


# this is ugly, we should find a better approach
# basically it build a list of #define from binary CFLAGS
uwsgi_cdef = []
uwsgi_defines = []
uwsgi_cflags = ffi.string(lib0.uwsgi_get_cflags()).split()
for cflag in uwsgi_cflags:
    if cflag.startswith('-D'):
        line = cflag[2:]
        if '=' in line:
            (key, value) = line.split('=', 1)
            uwsgi_cdef.append('#define %s ...' % key)
            uwsgi_defines.append('#define %s %s' % (key, value.replace('\\"','"').replace('""','"')))            
        else:
            uwsgi_cdef.append('#define %s ...' % line)
            uwsgi_defines.append('#define %s 1' % line)            
uwsgi_dot_h = ffi.string(lib0.uwsgi_get_dot_h())

# uwsgi definitions
cdefines = '''
%s

struct iovec {
	void *iov_base;
	size_t iov_len;
	...;
};

struct uwsgi_header {
	uint8_t modifier1;
	...;
};

struct wsgi_request {
	int fd;
	int async_id;
	uint16_t var_cnt;
	struct iovec *hvec;

	int async_ready_fd;
	int async_last_ready_fd;

	int suspended;