"""
QAPI types generator

Copyright IBM, Corp. 2011
Copyright (c) 2013-2018 Red Hat Inc.

Authors:
 Anthony Liguori <aliguori@us.ibm.com>
 Michael Roth <mdroth@linux.vnet.ibm.com>
 Markus Armbruster <armbru@redhat.com>

This work is licensed under the terms of the GNU GPL, version 2.
# See the COPYING file in the top-level directory.
"""

from typing import List, Optional

from .common import c_enum_const, c_name, mcgen
from .gen import (
    QAPISchemaModularCVisitor,
    gen_special_features,
    ifcontext,
)
from .schema import (
    QAPISchema,
    QAPISchemaAlternatives,
    QAPISchemaBranches,
    QAPISchemaEnumMember,
    QAPISchemaFeature,
    QAPISchemaIfCond,
    QAPISchemaObjectType,
    QAPISchemaObjectTypeMember,
    QAPISchemaType,
    QAPISchemaVariants,
)
from .source import QAPISourceInfo


# variants must be emitted before their container; track what has already
# been output
objects_seen = set()


def gen_enum_lookup(name: str,
                    members: List[QAPISchemaEnumMember],
                    prefix: Optional[str] = None) -> str:
    max_index = c_enum_const(name, '_MAX', prefix)
    feats = ''
    ret = mcgen('''

const QEnumLookup %(c_name)s_lookup = {
    .array = (const char *const[]) {
''',
                c_name=c_name(name))
    for memb in members:
        ret += memb.ifcond.gen_if()
        index = c_enum_const(name, memb.name, prefix)
        ret += mcgen('''
        [%(index)s] = "%(name)s",
''',
                     index=index, name=memb.name)
        ret += memb.ifcond.gen_endif()

        special_features = gen_special_features(memb.features)
        if special_features != '0':
            feats += mcgen('''
        [%(index)s] = %(special_features)s,
''',
                           index=index, special_features=special_features)

    if feats:
        ret += mcgen('''
    },
    .special_features = (const unsigned char[%(max_index)s]) {
''',
                     max_index=max_index)
        ret += feats

    ret += mcgen('''
    },
    .size = %(max_index)s
};
''',
                 max_index=max_index)
    return ret


def gen_enum(name: str,
             members: List[QAPISchemaEnumMember],
             prefix: Optional[str] = None) -> str:
    # append automatically generated _MAX value
    enum_members = members + [QAPISchemaEnumMember('_MAX', None)]

    ret = mcgen('''

typedef enum %(c_name)s {
''',
                c_name=c_name(name))

    for memb in enum_members:
        ret += memb.ifcond.gen_if()
        ret += mcgen('''
    %(c_enum)s,
''',
                     c_enum=c_enum_const(name, memb.name, prefix))
        ret += memb.ifcond.gen_endif()

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

    ret += mcgen('''

#define %(c_name)s_str(val) \\
    qapi_enum_lookup(&%(c_name)s_lookup, (val))

extern const QEnumLookup %(c_name)s_lookup;
''',
                 c_name=c_name(name))
    return ret


def gen_fwd_object_or_array(name: str) -> str:
    return mcgen('''

typedef struct %(c_name)s %(c_name)s;
''',
                 c_name=c_name(name))


def gen_array(name: str, element_type: QAPISchemaType) -> str:
    return mcgen('''

struct %(c_name)s {
    %(c_name)s *next;
    %(c_type)s value;
};
''',
                 c_name=c_name(name), c_type=element_type.c_type())


def gen_struct_members(members: List[QAPISchemaObjectTypeMember]) -> str:
    ret = ''
    for memb in members:
        ret += memb.ifcond.gen_if()
        if memb.need_has():
            ret += mcgen('''
    bool has_%(c_name)s;
''',
                         c_name=c_name(memb.name))
        ret += mcgen('''
    %(c_type)s %(c_name)s;
''',
                     c_type=memb.type.c_type(), c_name=c_name(memb.name))
        ret += memb.ifcond.gen_endif()
    return ret


def gen_object(name: str, ifcond: QAPISchemaIfCond,
               base: Optional[QAPISchemaObjectType],
               members: List[QAPISchemaObjectTypeMember],
               variants: Optional[QAPISchemaVariants]) -> str:
    if name in objects_seen:
        return ''
    objects_seen.add(name)

    ret = ''
    for var in variants.variants if variants else ():
        obj = var.type
        if not isinstance(obj, QAPISchemaObjectType):
            continue
        ret += gen_object(obj.name, obj.ifcond, obj.base,
                          obj.local_members, obj.branches)

    ret += mcgen('''

''')
    ret += ifcond.gen_if()
    ret += mcgen('''
struct %(c_name)s {
''',
                 c_name=c_name(name))

    if base:
        if not base.is_implicit():
            ret += mcgen('''
    /* Members inherited from %(c_name)s: */
''',
                         c_name=base.c_name())
        ret += gen_struct_members(base.members)
        if not base.is_implicit():
            ret += mcgen('''
    /* Own members: */
''')
    ret += gen_struct_members(members)

    if variants:
        ret += gen_variants(variants)

    # Make sure that all structs have at least one member; 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 or base.is_empty()) and not members and not variants:
        ret += mcgen('''
    char qapi_dummy_for_empty_struct;
''')

    ret += mcgen('''
};
''')
    ret += ifcond.gen_endif()

    return ret


def gen_upcast(name: str, base: QAPISchemaObjectType) -> str:
    # C makes const-correctness ugly.  We have to cast away const to let
    # this function work for both const and non-const obj.
    return mcgen('''

static inline %(base)s *qapi_%(c_name)s_base(const %(c_name)s *obj)
{
    return (%(base)s *)obj;
}
''',
                 c_name=c_name(name), base=base.c_name())


def gen_variants(variants: QAPISchemaVariants) -> str:
    ret = mcgen('''
    union { /* union tag is @%(c_name)s */
''',
                c_name=c_name(variants.tag_member.name))

    for var in variants.variants:
        if var.type.name == 'q_empty':
            continue
        ret += var.ifcond.gen_if()
        ret += mcgen('''
        %(c_type)s %(c_name)s;
''',
                     c_type=var.type.c_unboxed_type(),
                     c_name=c_name(var.name))
        ret += var.ifcond.gen_endif()

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

    return ret


def gen_type_cleanup_decl(name: str) -> str:
    ret = mcgen('''

void qapi_free_%(c_name)s(%(c_name)s *obj);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(%(c_name)s, qapi_free_%(c_name)s)
''',
                c_name=c_name(name))
    return ret


def gen_type_cleanup(name: str) -> str:
    ret = mcgen('''

void qapi_free_%(c_name)s(%(c_name)s *obj)
{
    Visitor *v;

    if (!obj) {
        return;
    }

    v = qapi_dealloc_visitor_new();
    visit_type_%(c_name)s(v, NULL, &obj, NULL);
    visit_free(v);
}
''',
                c_name=c_name(name))
    return ret


class QAPISchemaGenTypeVisitor(QAPISchemaModularCVisitor):

    def __init__(self, prefix: str):
        super().__init__(
            prefix, 'qapi-types', ' * Schema-defined QAPI types',
            ' * Built-in QAPI types', __doc__)

    def _begin_builtin_module(self) -> None:
        self._genc.preamble_add(mcgen('''
#include "qemu/osdep.h"
#include "qapi/dealloc-visitor.h"
#include "qapi/qapi-builtin-types.h"
#include "qapi/qapi-builtin-visit.h"
'''))
        self._genh.preamble_add(mcgen('''
#include "qapi/util.h"
'''))

    def _begin_user_module(self, name: str) -> None:
        types = self._module_basename('qapi-types', name)
        visit = self._module_basename('qapi-visit', name)
        self._genc.preamble_add(mcgen('''
#include "qemu/osdep.h"
#include "qapi/dealloc-visitor.h"
#include "%(types)s.h"
#include "%(visit)s.h"
''',
                                      types=types, visit=visit))
        self._genh.preamble_add(mcgen('''
#include "qapi/qapi-builtin-types.h"
'''))

    def visit_begin(self, schema: QAPISchema) -> None:
        # gen_object() is recursive, ensure it doesn't visit the empty type
        objects_seen.add(schema.the_empty_object_type.name)

    def _gen_type_cleanup(self, name: str) -> None:
        self._genh.add(gen_type_cleanup_decl(name))
        self._genc.add(gen_type_cleanup(name))

    def visit_enum_type(self,
                        name: str,
                        info: Optional[QAPISourceInfo],
                        ifcond: QAPISchemaIfCond,
                        features: List[QAPISchemaFeature],
                        members: List[QAPISchemaEnumMember],
                        prefix: Optional[str]) -> None:
        with ifcontext(ifcond, self._genh, self._genc):
            self._genh.preamble_add(gen_enum(name, members, prefix))
            self._genc.add(gen_enum_lookup(name, members, prefix))

    def visit_array_type(self,
                         name: str,
                         info: Optional[QAPISourceInfo],
                         ifcond: QAPISchemaIfCond,
                         element_type: QAPISchemaType) -> None:
        with ifcontext(ifcond, self._genh, self._genc):
            self._genh.preamble_add(gen_fwd_object_or_array(name))
            self._genh.add(gen_array(name, element_type))
            self._gen_type_cleanup(name)

    def visit_object_type(self,
                          name: str,
                          info: Optional[QAPISourceInfo],
                          ifcond: QAPISchemaIfCond,
                          features: List[QAPISchemaFeature],
                          base: Optional[QAPISchemaObjectType],
                          members: List[QAPISchemaObjectTypeMember],
                          branches: Optional[QAPISchemaBranches]) -> None:
        # Nothing to do for the special empty builtin
        if name == 'q_empty':
            return
        with ifcontext(ifcond, self._genh):
            self._genh.preamble_add(gen_fwd_object_or_array(name))
        self._genh.add(gen_object(name, ifcond, base, members, branches))
        with ifcontext(ifcond, self._genh, self._genc):
            if base and not base.is_implicit():
                self._genh.add(gen_upcast(name, base))
            # TODO Worth changing the visitor signature, so we could
            # directly use rather than repeat type.is_implicit()?
            if not name.startswith('q_'):
                # implicit types won't be directly allocated/freed
                self._gen_type_cleanup(name)

    def visit_alternate_type(self,
                             name: str,
                             info: Optional[QAPISourceInfo],
                             ifcond: QAPISchemaIfCond,
                             features: List[QAPISchemaFeature],
                             alternatives: QAPISchemaAlternatives) -> None:
        with ifcontext(ifcond, self._genh):
            self._genh.preamble_add(gen_fwd_object_or_array(name))
        self._genh.add(gen_object(name, ifcond, None,
                                  [alternatives.tag_member], alternatives))
        with ifcontext(ifcond, self._genh, self._genc):
            self._gen_type_cleanup(name)


def gen_types(schema: QAPISchema,
              output_dir: str,
              prefix: str,
              opt_builtins: bool) -> None:
    vis = QAPISchemaGenTypeVisitor(prefix)
    schema.visit(vis)
    vis.write(output_dir, opt_builtins)
