#
# QAPI types generator
#
# Copyright IBM, Corp. 2011
#
# Authors:
#  Anthony Liguori <aliguori@us.ibm.com>
#
# This work is licensed under the terms of the GNU GPL, version 2.
# See the COPYING file in the top-level directory.

from ordereddict import OrderedDict
from qapi import *
import sys
import os
import getopt
import errno

def generate_fwd_struct(name, members, builtin_type=False):
    if builtin_type:
        return mcgen('''

typedef struct %(name)sList
{
    union {
        %(type)s value;
        uint64_t padding;
    };
    struct %(name)sList *next;
} %(name)sList;
''',
                     type=c_type(name),
                     name=name)

    return mcgen('''

typedef struct %(name)s %(name)s;

typedef struct %(name)sList
{
    union {
        %(name)s *value;
        uint64_t padding;
    };
    struct %(name)sList *next;
} %(name)sList;
''',
                 name=name)

def generate_fwd_enum_struct(name, members):
    return mcgen('''
typedef struct %(name)sList
{
    union {
        %(name)s value;
        uint64_t padding;
    };
    struct %(name)sList *next;
} %(name)sList;
''',
                 name=name)

def generate_struct_fields(members):
    ret = ''

    for argname, argentry, optional, structured in parse_args(members):
        if optional:
            ret += mcgen('''
    bool has_%(c_name)s;
''',
                         c_name=c_var(argname))
        if structured:
            push_indent()
            ret += generate_struct({ "field": argname, "data": argentry})
            pop_indent()
        else:
            ret += mcgen('''
    %(c_type)s %(c_name)s;
''',
                     c_type=c_type(argentry), c_name=c_var(argname))

    return ret

def generate_struct(expr):

    structname = expr.get('struct', "")
    fieldname = expr.get('field', "")
    members = expr['data']
    base = expr.get('base')

    ret = mcgen('''
struct %(name)s
{
''',
          name=structname)

    if base:
        ret += generate_struct_fields({'base': base})

    ret += generate_struct_fields(members)

    # Make sure that all structs have at least one field; this avoids
    # potential issues with attempting to malloc space for zero-length structs
    # in C, and also incompatibility with C++ (where an empty struct is size 1).
    if not base and not members:
            ret += mcgen('''
    char qapi_dummy_field_for_empty_struct;
''')

    if len(fieldname):
        fieldname = " " + fieldname
    ret += mcgen('''
}%(field)s;
''',
            field=fieldname)

    return ret

def generate_enum_lookup(name, values):
    ret = mcgen('''
const char *%(name)s_lookup[] = {
''',
                         name=name)
    i = 0
    for value in values:
        index = generate_enum_full_value(name, value)
        ret += mcgen('''
    [%(index)s] = "%(value)s",
''',
                     index = index, value = value)

    max_index = generate_enum_full_value(name, 'MAX')
    ret += mcgen('''
    [%(max_index)s] = NULL,
};

''',
        max_index=max_index)
    return ret

def generate_enum(name, values):
    lookup_decl = mcgen('''
extern const char *%(name)s_lookup[];
''',
                name=name)

    enum_decl = mcgen('''
typedef enum %(name)s
{
''',
                name=name)

    # append automatically generated _MAX value
    enum_values = values + [ 'MAX' ]

    i = 0
    for value in enum_values:
        enum_full_value = generate_enum_full_value(name, value)
        enum_decl += mcgen('''
    %(enum_full_value)s = %(i)d,
''',
                     enum_full_value = enum_full_value,
                     i=i)
        i += 1

    enum_decl += mcgen('''
} %(name)s;
''',
                 name=name)

    return lookup_decl + enum_decl

def generate_alternate_qtypes(expr):

    name = expr['alternate']
    members = expr['data']

    ret = mcgen('''
const int %(name)s_qtypes[QTYPE_MAX] = {
''',
    name=name)

    for key in members:
        qtype = find_alternate_member_qtype(members[key])
        assert qtype, "Invalid alternate member"

        ret += mcgen('''
    [ %(qtype)s ] = %(abbrev)s_KIND_%(enum)s,
''',
        qtype = qtype,
        abbrev = de_camel_case(name).upper(),
        enum = c_fun(de_camel_case(key),False).upper())

    ret += mcgen('''
};
''')
    return ret


def generate_union(expr, meta):

    name = expr[meta]
    typeinfo = expr['data']

    base = expr.get('base')
    discriminator = expr.get('discriminator')

    enum_define = discriminator_find_enum_define(expr)
    if enum_define:
        discriminator_type_name = enum_define['enum_name']
    else:
        discriminator_type_name = '%sKind' % (name)

    ret = mcgen('''
struct %(name)s
{
    %(discriminator_type_name)s kind;
    union {
        void *data;
''',
                name=name,
                discriminator_type_name=discriminator_type_name)

    for key in typeinfo:
        ret += mcgen('''
        %(c_type)s %(c_name)s;
''',
                     c_type=c_type(typeinfo[key]),
                     c_name=c_fun(key))

    ret += mcgen('''
    };
''')

    if base:
        assert discriminator
        base_fields = find_struct(base)['data'].copy()
        del base_fields[discriminator]
        ret += generate_struct_fields(base_fields)
    else:
        assert not discriminator

    ret += mcgen('''
};
''')
    if meta == 'alternate':
        ret += mcgen('''
extern const int %(name)s_qtypes[];
''',
            name=name)


    return ret

def generate_type_cleanup_decl(name):
    ret = mcgen('''
void qapi_free_%(type)s(%(c_type)s obj);
''',
                c_type=c_type(name),type=name)
    return ret

def generate_type_cleanup(name):
    ret = mcgen('''

void qapi_free_%(type)s(%(c_type)s obj)
{
    QapiDeallocVisitor *md;
    Visitor *v;

    if (!obj) {
        return;
    }

    md = qapi_dealloc_visitor_new();
    v = qapi_dealloc_get_visitor(md);
    visit_type_%(type)s(v, &obj, NULL, NULL);
    qapi_dealloc_visitor_cleanup(md);
}
''',
                c_type=c_type(name),type=name)
    return ret


try:
    opts, args = getopt.gnu_getopt(sys.argv[1:], "chbp:i:o:",
                                   ["source", "header", "builtins",
                                    "prefix=", "input-file=", "output-dir="])
except getopt.GetoptError, err:
    print str(err)
    sys.exit(1)

output_dir = ""
input_file = ""
prefix = ""
c_file = 'qapi-types.c'
h_file = 'qapi-types.h'

do_c = False
do_h = False
do_builtins = False

for o, a in opts:
    if o in ("-p", "--prefix"):
        prefix = a
    elif o in ("-i", "--input-file"):
        input_file = a
    elif o in ("-o", "--output-dir"):
        output_dir = a + "/"
    elif o in ("-c", "--source"):
        do_c = True
    elif o in ("-h", "--header"):
        do_h = True
    elif o in ("-b", "--builtins"):
        do_builtins = True

if not do_c and not do_h:
    do_c = True
    do_h = True

c_file = output_dir + prefix + c_file
h_file = output_dir + prefix + h_file

try:
    os.makedirs(output_dir)
except os.error, e:
    if e.errno != errno.EEXIST:
        raise

def maybe_open(really, name, opt):
    if really:
        return open(name, opt)
    else:
        import StringIO
        return StringIO.StringIO()

fdef = maybe_open(do_c, c_file, 'w')
fdecl = maybe_open(do_h, h_file, 'w')

fdef.write(mcgen('''
/* AUTOMATICALLY GENERATED, DO NOT MODIFY */

/*
 * deallocation functions for schema-defined QAPI types
 *
 * Copyright IBM, Corp. 2011
 *
 * Authors:
 *  Anthony Liguori   <aliguori@us.ibm.com>
 *  Michael Roth      <mdroth@linux.vnet.ibm.com>
 *
 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
 * See the COPYING.LIB file in the top-level directory.
 *
 */

#include "qapi/dealloc-visitor.h"
#include "%(prefix)sqapi-types.h"
#include "%(prefix)sqapi-visit.h"

''',             prefix=prefix))

fdecl.write(mcgen('''
/* AUTOMATICALLY GENERATED, DO NOT MODIFY */

/*
 * schema-defined QAPI types
 *
 * Copyright IBM, Corp. 2011
 *
 * Authors:
 *  Anthony Liguori   <aliguori@us.ibm.com>
 *
 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
 * See the COPYING.LIB file in the top-level directory.
 *
 */

#ifndef %(guard)s
#define %(guard)s

#include <stdbool.h>
#include <stdint.h>

''',
                  guard=guardname(h_file)))

exprs = parse_schema(input_file)
exprs = filter(lambda expr: not expr.has_key('gen'), exprs)

fdecl.write(guardstart("QAPI_TYPES_BUILTIN_STRUCT_DECL"))
for typename in builtin_types.keys():
    fdecl.write(generate_fwd_struct(typename, None, builtin_type=True))
fdecl.write(guardend("QAPI_TYPES_BUILTIN_STRUCT_DECL"))

for expr in exprs:
    ret = "\n"
    if expr.has_key('struct'):
        ret += generate_fwd_struct(expr['struct'], expr['data'])
    elif expr.has_key('enum'):
        ret += generate_enum(expr['enum'], expr['data']) + "\n"
        ret += generate_fwd_enum_struct(expr['enum'], expr['data'])
        fdef.write(generate_enum_lookup(expr['enum'], expr['data']))
    elif expr.has_key('union'):
        ret += generate_fwd_struct(expr['union'], expr['data']) + "\n"
        enum_define = discriminator_find_enum_define(expr)
        if not enum_define:
            ret += generate_enum('%sKind' % expr['union'], expr['data'].keys())
            fdef.write(generate_enum_lookup('%sKind' % expr['union'],
                                            expr['data'].keys()))
    elif expr.has_key('alternate'):
        ret += generate_fwd_struct(expr['alternate'], expr['data']) + "\n"
        ret += generate_enum('%sKind' % expr['alternate'], expr['data'].keys())
        fdef.write(generate_enum_lookup('%sKind' % expr['alternate'],
                                        expr['data'].keys()))
        fdef.write(generate_alternate_qtypes(expr))
    else:
        continue
    fdecl.write(ret)

# to avoid header dependency hell, we always generate declarations
# for built-in types in our header files and simply guard them
fdecl.write(guardstart("QAPI_TYPES_BUILTIN_CLEANUP_DECL"))
for typename in builtin_types.keys():
    fdecl.write(generate_type_cleanup_decl(typename + "List"))
fdecl.write(guardend("QAPI_TYPES_BUILTIN_CLEANUP_DECL"))

# ...this doesn't work for cases where we link in multiple objects that
# have the functions defined, so we use -b option to provide control
# over these cases
if do_builtins:
    fdef.write(guardstart("QAPI_TYPES_BUILTIN_CLEANUP_DEF"))
    for typename in builtin_types.keys():
        fdef.write(generate_type_cleanup(typename + "List"))
    fdef.write(guardend("QAPI_TYPES_BUILTIN_CLEANUP_DEF"))

for expr in exprs:
    ret = "\n"
    if expr.has_key('struct'):
        ret += generate_struct(expr) + "\n"
        ret += generate_type_cleanup_decl(expr['struct'] + "List")
        fdef.write(generate_type_cleanup(expr['struct'] + "List") + "\n")
        ret += generate_type_cleanup_decl(expr['struct'])
        fdef.write(generate_type_cleanup(expr['struct']) + "\n")
    elif expr.has_key('union'):
        ret += generate_union(expr, 'union')
        ret += generate_type_cleanup_decl(expr['union'] + "List")
        fdef.write(generate_type_cleanup(expr['union'] + "List") + "\n")
        ret += generate_type_cleanup_decl(expr['union'])
        fdef.write(generate_type_cleanup(expr['union']) + "\n")
    elif expr.has_key('alternate'):
        ret += generate_union(expr, 'alternate')
        ret += generate_type_cleanup_decl(expr['alternate'] + "List")
        fdef.write(generate_type_cleanup(expr['alternate'] + "List") + "\n")
        ret += generate_type_cleanup_decl(expr['alternate'])
        fdef.write(generate_type_cleanup(expr['alternate']) + "\n")
    elif expr.has_key('enum'):
        ret += generate_type_cleanup_decl(expr['enum'] + "List")
        fdef.write(generate_type_cleanup(expr['enum'] + "List") + "\n")
    else:
        continue
    fdecl.write(ret)

fdecl.write('''
#endif
''')

fdecl.flush()
fdecl.close()

fdef.flush()
fdef.close()
