################################################################################
#  THIS FILE IS 100% GENERATED BY ZPROJECT; DO NOT EDIT EXCEPT EXPERIMENTALLY  #
#  Read the zproject/README.md for information about making permanent changes. #
################################################################################

from __future__ import print_function
import os
import re
import sys

import subprocess
def pkgconfig_installed ():
   try:
        subprocess.check_output (["pkg-config", "--version"])
        return True
   except subprocess.CalledProcessError:
        return False

def pkgconfig_kwargs (libs):
    """If pkg-config is available, then return kwargs for set_source based on pkg-config output

    It setup include_dirs, library_dirs, libraries and define_macros
    """

    # make API great again!
    if isinstance (libs, (str, bytes)):
        libs = (libs, )

    # drop starting -I -L -l from cflags
    def dropILl (string):
        def _dropILl (string):
            if string.startswith (b"-I") or string.startswith (b"-L") or string.startswith (b"-l"):
                return string [2:]
        return [_dropILl (x) for x in string.split ()]

    # convert -Dfoo=bar to list of tuples [("foo", "bar")] expected by cffi
    def macros (string):
        def _macros (string):
            return tuple (string [2:].split (b'=', 2))
        return [_macros (x) for x in string.split () if x.startswith (b"-D")]

    # pkg-config call
    def pc (libname, *args):
        a = ["pkg-config", "--print-errors"]
        a.extend (args)
        a.append (libname)
        return subprocess.check_output (a)

    # return kwargs for given libname
    def kwargs (libname):
        return {
                "include_dirs" : dropILl (pc (libname, "--cflags-only-I")),
                "library_dirs" : dropILl (pc (libname, "--libs-only-L")),
                "libraries" : dropILl (pc (libname, "--libs-only-l")),
                "define_macros" : macros (pc (libname, "--cflags")),
                }

    # merge all arguments together
    ret = {}
    for libname in libs:
        foo = kwargs (libname)
        for key, value in foo.items ():
            if key not in ret:
                ret [key] = value
            else:
                ret [key].extend (value)

    # Python3 and strict unicode
    for key, value in ret.items ():
        if isinstance (value, bytes):
            ret [key] = value.decode ("utf-8")
        elif isinstance (value, list):
            if len (value) == 0:
                continue
            if isinstance (value[0], tuple):
                ret [key] = [(v[0].decode ("utf-8"), v[1].decode ("utf-8")) for v in value]
            else:
                ret [key] = [v.decode ("utf-8") for v in value]

    return ret

if not pkgconfig_installed ():
    print ("ERROR: build without pkg-config not supported", file=sys.stderr)
    sys.exit (1)

kwargs = pkgconfig_kwargs ([
    "libzmq",
    "uuid",
    "libsystemd",
    "liblz4",
    "libcurl",
    "nss",
    "libmicrohttpd",
    "libczmq"
])
import cffi
# can't import does not work, read and exec manually
with open (os.path.join (
    os.path.dirname (__file__),
    "cdefs.py"), 'r') as fp:
    cdefs_py = fp.read()
gl = {}
exec (cdefs_py, gl)
czmq_cdefs = gl ["czmq_cdefs"]

ffibuilder = cffi.FFI ()
ffibuilder.set_source ("czmq_cffi.native", "#include <czmq.h>", **kwargs)

# Custom setup for czmq
for item in czmq_cdefs:
    ffibuilder.cdef(item)

ffidestructorbuilder = cffi.FFI ()
ffidestructorbuilder.cdef('''
void
   zactor_destroy_py (void *self);

void
   zargs_destroy_py (void *self);

void
   zarmour_destroy_py (void *self);

void
   zcert_destroy_py (void *self);

void
   zcertstore_destroy_py (void *self);

void
   zchunk_destroy_py (void *self);

void
   zconfig_destroy_py (void *self);

void
   zdigest_destroy_py (void *self);

void
   zdir_destroy_py (void *self);

void
   zdir_patch_destroy_py (void *self);

void
   zfile_destroy_py (void *self);

void
   zframe_destroy_py (void *self);

void
   zhash_destroy_py (void *self);

void
   zhashx_destroy_py (void *self);

void
   ziflist_destroy_py (void *self);

void
   zlist_destroy_py (void *self);

void
   zlistx_destroy_py (void *self);

void
   zloop_destroy_py (void *self);

void
   zmsg_destroy_py (void *self);

void
   zpoller_destroy_py (void *self);

void
   zproc_destroy_py (void *self);

void
   zsock_destroy_py (void *self);

void
   ztimerset_destroy_py (void *self);

void
   ztrie_destroy_py (void *self);

void
   zuuid_destroy_py (void *self);

void
   zhttp_client_destroy_py (void *self);

void
   zhttp_server_destroy_py (void *self);

void
   zhttp_server_options_destroy_py (void *self);

void
   zhttp_request_destroy_py (void *self);

void
   zhttp_response_destroy_py (void *self);

void
   zosc_destroy_py (void *self);

''')

ffidestructorbuilder.set_source ("czmq_cffi.destructors", '''
#include <czmq.h>
void
zactor_destroy_py (void *self)
{
   zactor_destroy ((zactor_t **) &self);
}

void
zargs_destroy_py (void *self)
{
   zargs_destroy ((zargs_t **) &self);
}

void
zarmour_destroy_py (void *self)
{
   zarmour_destroy ((zarmour_t **) &self);
}

void
zcert_destroy_py (void *self)
{
   zcert_destroy ((zcert_t **) &self);
}

void
zcertstore_destroy_py (void *self)
{
   zcertstore_destroy ((zcertstore_t **) &self);
}

void
zchunk_destroy_py (void *self)
{
   zchunk_destroy ((zchunk_t **) &self);
}

void
zconfig_destroy_py (void *self)
{
   zconfig_destroy ((zconfig_t **) &self);
}

void
zdigest_destroy_py (void *self)
{
   zdigest_destroy ((zdigest_t **) &self);
}

void
zdir_destroy_py (void *self)
{
   zdir_destroy ((zdir_t **) &self);
}

void
zdir_patch_destroy_py (void *self)
{
   zdir_patch_destroy ((zdir_patch_t **) &self);
}

void
zfile_destroy_py (void *self)
{
   zfile_destroy ((zfile_t **) &self);
}

void
zframe_destroy_py (void *self)
{
   zframe_destroy ((zframe_t **) &self);
}

void
zhash_destroy_py (void *self)
{
   zhash_destroy ((zhash_t **) &self);
}

void
zhashx_destroy_py (void *self)
{
   zhashx_destroy ((zhashx_t **) &self);
}

void
ziflist_destroy_py (void *self)
{
   ziflist_destroy ((ziflist_t **) &self);
}

void
zlist_destroy_py (void *self)
{
   zlist_destroy ((zlist_t **) &self);
}

void
zlistx_destroy_py (void *self)
{
   zlistx_destroy ((zlistx_t **) &self);
}

void
zloop_destroy_py (void *self)
{
   zloop_destroy ((zloop_t **) &self);
}

void
zmsg_destroy_py (void *self)
{
   zmsg_destroy ((zmsg_t **) &self);
}

void
zpoller_destroy_py (void *self)
{
   zpoller_destroy ((zpoller_t **) &self);
}

void
zproc_destroy_py (void *self)
{
   zproc_destroy ((zproc_t **) &self);
}

void
zsock_destroy_py (void *self)
{
   zsock_destroy ((zsock_t **) &self);
}

void
ztimerset_destroy_py (void *self)
{
   ztimerset_destroy ((ztimerset_t **) &self);
}

void
ztrie_destroy_py (void *self)
{
   ztrie_destroy ((ztrie_t **) &self);
}

void
zuuid_destroy_py (void *self)
{
   zuuid_destroy ((zuuid_t **) &self);
}

void
zhttp_client_destroy_py (void *self)
{
   zhttp_client_destroy ((zhttp_client_t **) &self);
}

void
zhttp_server_destroy_py (void *self)
{
   zhttp_server_destroy ((zhttp_server_t **) &self);
}

void
zhttp_server_options_destroy_py (void *self)
{
   zhttp_server_options_destroy ((zhttp_server_options_t **) &self);
}

void
zhttp_request_destroy_py (void *self)
{
   zhttp_request_destroy ((zhttp_request_t **) &self);
}

void
zhttp_response_destroy_py (void *self)
{
   zhttp_response_destroy ((zhttp_response_t **) &self);
}

void
zosc_destroy_py (void *self)
{
   zosc_destroy ((zosc_t **) &self);
}

''', **kwargs)

if __name__ == "__main__":
    ffibuilder.compile (verbose=True)
    ffidestructorbuilder.compile (verbose=True)
