"""
QAPI visitor generator

Copyright IBM, Corp. 2011
Copyright (C) 2014-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,
    indent,
    mcgen,
)
from .gen import (
    QAPISchemaModularCVisitor,
    gen_special_features,
    ifcontext,
)
from .schema import (
    QAPISchema,
    QAPISchemaEnumMember,
    QAPISchemaEnumType,
    QAPISchemaFeature,
    QAPISchemaIfCond,
    QAPISchemaObjectType,
    QAPISchemaObjectTypeMember,
    QAPISchemaType,
    QAPISchemaVariants,
)
from .source import QAPISourceInfo


def gen_visit_decl(name: str, scalar: bool = False) -> str:
    c_type = c_name(name) + ' *'
    if not scalar:
        c_type += '*'
    return mcgen('''

bool visit_type_%(c_name)s(Visitor *v, const char *name,
                 %(c_type)sobj, Error **errp);
''',
                 c_name=c_name(name), c_type=c_type)


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

bool visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp);
''',
                 c_name=c_name(name))


def gen_visit_object_members(name: str,
                             base: Optional[QAPISchemaObjectType],
                             members: List[QAPISchemaObjectTypeMember],
                             variants: Optional[QAPISchemaVariants]) -> str:
    ret = mcgen('''

bool visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp)
{
''',
                c_name=c_name(name))

    sep = ''
    for memb in members:
        if memb.optional and not memb.need_has():
            ret += memb.ifcond.gen_if()
            ret += mcgen('''
    bool has_%(c_name)s = !!obj->%(c_name)s;
''',
                         c_name=c_name(memb.name))
            sep = '\n'
            ret += memb.ifcond.gen_endif()
    ret += sep

    if base:
        ret += mcgen('''
    if (!visit_type_%(c_type)s_members(v, (%(c_type)s *)obj, errp)) {
        return false;
    }
''',
                     c_type=base.c_name())

    for memb in members:
        ret += memb.ifcond.gen_if()
        if memb.optional:
            has = 'has_' + c_name(memb.name)
            if memb.need_has():
                has = 'obj->' + has
            ret += mcgen('''
    if (visit_optional(v, "%(name)s", &%(has)s)) {
''',
                         name=memb.name, has=has)
            indent.increase()
        special_features = gen_special_features(memb.features)
        if special_features != '0':
            ret += mcgen('''
    if (visit_policy_reject(v, "%(name)s", %(special_features)s, errp)) {
        return false;
    }
    if (!visit_policy_skip(v, "%(name)s", %(special_features)s)) {
''',
                         name=memb.name, special_features=special_features)
            indent.increase()
        ret += mcgen('''
    if (!visit_type_%(c_type)s(v, "%(name)s", &obj->%(c_name)s, errp)) {
        return false;
    }
''',
                     c_type=memb.type.c_name(), name=memb.name,
                     c_name=c_name(memb.name))
        if special_features != '0':
            indent.decrease()
            ret += mcgen('''
    }
''')
        if memb.optional:
            indent.decrease()
            ret += mcgen('''
    }
''')
        ret += memb.ifcond.gen_endif()

    if variants:
        tag_member = variants.tag_member
        assert isinstance(tag_member.type, QAPISchemaEnumType)

        ret += mcgen('''
    switch (obj->%(c_name)s) {
''',
                     c_name=c_name(tag_member.name))

        for var in variants.variants:
            case_str = c_enum_const(tag_member.type.name, var.name,
                                    tag_member.type.prefix)
            ret += var.ifcond.gen_if()
            if var.type.name == 'q_empty':
                # valid variant and nothing to do
                ret += mcgen('''
    case %(case)s:
        break;
''',
                             case=case_str)
            else:
                ret += mcgen('''
    case %(case)s:
        return visit_type_%(c_type)s_members(v, &obj->u.%(c_name)s, errp);
''',
                             case=case_str,
                             c_type=var.type.c_name(), c_name=c_name(var.name))

            ret += var.ifcond.gen_endif()
        ret += mcgen('''
    default:
        abort();
    }
''')

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


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

bool visit_type_%(c_name)s(Visitor *v, const char *name,
                 %(c_name)s **obj, Error **errp)
{
    bool ok = false;
    %(c_name)s *tail;
    size_t size = sizeof(**obj);

    if (!visit_start_list(v, name, (GenericList **)obj, size, errp)) {
        return false;
    }

    for (tail = *obj; tail;
         tail = (%(c_name)s *)visit_next_list(v, (GenericList *)tail, size)) {
        if (!visit_type_%(c_elt_type)s(v, NULL, &tail->value, errp)) {
            goto out_obj;
        }
    }

    ok = visit_check_list(v, errp);
out_obj:
    visit_end_list(v, (void **)obj);
    if (!ok && visit_is_input(v)) {
        qapi_free_%(c_name)s(*obj);
        *obj = NULL;
    }
    return ok;
}
''',
                 c_name=c_name(name), c_elt_type=element_type.c_name())


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

bool visit_type_%(c_name)s(Visitor *v, const char *name,
                 %(c_name)s *obj, Error **errp)
{
    int value = *obj;
    bool ok = visit_type_enum(v, name, &value, &%(c_name)s_lookup, errp);
    *obj = value;
    return ok;
}
''',
                 c_name=c_name(name))


def gen_visit_alternate(name: str, variants: QAPISchemaVariants) -> str:
    ret = mcgen('''

bool visit_type_%(c_name)s(Visitor *v, const char *name,
                 %(c_name)s **obj, Error **errp)
{
    bool ok = false;

    if (!visit_start_alternate(v, name, (GenericAlternate **)obj,
                               sizeof(**obj), errp)) {
        return false;
    }
    if (!*obj) {
        /* incomplete */
        assert(visit_is_dealloc(v));
        ok = true;
        goto out_obj;
    }
    switch ((*obj)->type) {
''',
                c_name=c_name(name))

    for var in variants.variants:
        ret += var.ifcond.gen_if()
        ret += mcgen('''
    case %(case)s:
''',
                     case=var.type.alternate_qtype())
        if isinstance(var.type, QAPISchemaObjectType):
            ret += mcgen('''
        if (!visit_start_struct(v, name, NULL, 0, errp)) {
            break;
        }
        if (visit_type_%(c_type)s_members(v, &(*obj)->u.%(c_name)s, errp)) {
            ok = visit_check_struct(v, errp);
        }
        visit_end_struct(v, NULL);
''',
                         c_type=var.type.c_name(),
                         c_name=c_name(var.name))
        else:
            ret += mcgen('''
        ok = visit_type_%(c_type)s(v, name, &(*obj)->u.%(c_name)s, errp);
''',
                         c_type=var.type.c_name(),
                         c_name=c_name(var.name))
        ret += mcgen('''
        break;
''')
        ret += var.ifcond.gen_endif()

    ret += mcgen('''
    case QTYPE_NONE:
        abort();
    default:
        assert(visit_is_input(v));
        error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
                   "%(name)s");
        /* Avoid passing invalid *obj to qapi_free_%(c_name)s() */
        g_free(*obj);
        *obj = NULL;
    }
out_obj:
    visit_end_alternate(v, (void **)obj);
    if (!ok && visit_is_input(v)) {
        qapi_free_%(c_name)s(*obj);
        *obj = NULL;
    }
    return ok;
}
''',
                 name=name, c_name=c_name(name))

    return ret


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

bool visit_type_%(c_name)s(Visitor *v, const char *name,
                 %(c_name)s **obj, Error **errp)
{
    bool ok = false;

    if (!visit_start_struct(v, name, (void **)obj, sizeof(%(c_name)s), errp)) {
        return false;
    }
    if (!*obj) {
        /* incomplete */
        assert(visit_is_dealloc(v));
        ok = true;
        goto out_obj;
    }
    if (!visit_type_%(c_name)s_members(v, *obj, errp)) {
        goto out_obj;
    }
    ok = visit_check_struct(v, errp);
out_obj:
    visit_end_struct(v, (void **)obj);
    if (!ok && visit_is_input(v)) {
        qapi_free_%(c_name)s(*obj);
        *obj = NULL;
    }
    return ok;
}
''',
                 c_name=c_name(name))


class QAPISchemaGenVisitVisitor(QAPISchemaModularCVisitor):

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

    def _begin_builtin_module(self) -> None:
        self._genc.preamble_add(mcgen('''
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qapi/qapi-builtin-visit.h"
'''))
        self._genh.preamble_add(mcgen('''
#include "qapi/visitor.h"
#include "qapi/qapi-builtin-types.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/error.h"
#include "qapi/qmp/qerror.h"
#include "%(visit)s.h"
''',
                                      visit=visit))
        self._genh.preamble_add(mcgen('''
#include "qapi/qapi-builtin-visit.h"
#include "%(types)s.h"

''',
                                      types=types))

    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.add(gen_visit_decl(name, scalar=True))
            self._genc.add(gen_visit_enum(name))

    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.add(gen_visit_decl(name))
            self._genc.add(gen_visit_list(name, element_type))

    def visit_object_type(self,
                          name: str,
                          info: Optional[QAPISourceInfo],
                          ifcond: QAPISchemaIfCond,
                          features: List[QAPISchemaFeature],
                          base: Optional[QAPISchemaObjectType],
                          members: List[QAPISchemaObjectTypeMember],
                          variants: Optional[QAPISchemaVariants]) -> None:
        # Nothing to do for the special empty builtin
        if name == 'q_empty':
            return
        with ifcontext(ifcond, self._genh, self._genc):
            self._genh.add(gen_visit_members_decl(name))
            self._genc.add(gen_visit_object_members(name, base,
                                                    members, variants))
            # TODO Worth changing the visitor signature, so we could
            # directly use rather than repeat type.is_implicit()?
            if not name.startswith('q_'):
                # only explicit types need an allocating visit
                self._genh.add(gen_visit_decl(name))
                self._genc.add(gen_visit_object(name))

    def visit_alternate_type(self,
                             name: str,
                             info: Optional[QAPISourceInfo],
                             ifcond: QAPISchemaIfCond,
                             features: List[QAPISchemaFeature],
                             variants: QAPISchemaVariants) -> None:
        with ifcontext(ifcond, self._genh, self._genc):
            self._genh.add(gen_visit_decl(name))
            self._genc.add(gen_visit_alternate(name, variants))


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