# Copyright (C) 2020 Red Hat Inc.
#
# Authors:
#  Eduardo Habkost <ehabkost@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 .regexps import *
from .qom_macros import *
from .qom_type_info import *

def test_res() -> None:
    def fullmatch(regexp, s):
        return re.fullmatch(regexp, s, re.MULTILINE)

    assert fullmatch(RE_IDENTIFIER, 'sizeof')
    assert fullmatch(RE_IDENTIFIER, 'X86CPU')
    assert fullmatch(RE_FUN_CALL, 'sizeof(X86CPU)')
    assert fullmatch(RE_IDENTIFIER, 'X86_CPU_TYPE_NAME')
    assert fullmatch(RE_SIMPLE_VALUE, '"base"')
    print(RE_FUN_CALL)
    assert fullmatch(RE_FUN_CALL, 'X86_CPU_TYPE_NAME("base")')
    print(RE_TI_FIELD_INIT)
    assert fullmatch(RE_TI_FIELD_INIT, '.name = X86_CPU_TYPE_NAME("base"),\n')


    assert fullmatch(RE_MACRO_CONCAT, 'TYPE_ASPEED_GPIO "-ast2600"')
    assert fullmatch(RE_EXPRESSION, 'TYPE_ASPEED_GPIO "-ast2600"')

    print(RE_MACRO_DEFINE)
    assert re.search(RE_MACRO_DEFINE, r'''
    #define OFFSET_CHECK(c)                     \
    do {                                        \
        if (!(c)) {                             \
            goto bad_offset;                    \
        }                                       \
    } while (0)
    ''', re.MULTILINE)

    print(RE_CHECK_MACRO)
    print(CPP_SPACE)
    assert not re.match(RE_CHECK_MACRO, r'''
    #define OFFSET_CHECK(c)                     \
    do {                                        \
        if (!(c)) {                             \
            goto bad_offset;                    \
        }                                       \
    } while (0)''', re.MULTILINE)

    print(RE_CHECK_MACRO)
    assert fullmatch(RE_CHECK_MACRO, r'''#define PCI_DEVICE(obj) \
                     OBJECT_CHECK(PCIDevice, (obj), TYPE_PCI_DEVICE)
''')
    assert fullmatch(RE_CHECK_MACRO, r'''#define COLLIE_MACHINE(obj) \
                     OBJECT_CHECK(CollieMachineState, obj, TYPE_COLLIE_MACHINE)
''')

    print(RE_TYPEINFO_START)
    assert re.search(RE_TYPEINFO_START, r'''
    cc->open = qmp_chardev_open_file;
}

static const TypeInfo char_file_type_info = {
    .name = TYPE_CHARDEV_FILE,
#ifdef _WIN32
    .parent = TYPE_CHARDEV_WIN,
''', re.MULTILINE)
    assert re.search(RE_TYPEINFO_START, r'''
        TypeInfo ti = {
            .name = armsse_variants[i].name,
            .parent = TYPE_ARMSSE,
            .class_init = armsse_class_init,
            .class_data = (void *)&armsse_variants[i],
        };''', re.MULTILINE)

    print(RE_ARRAY_ITEM)
    assert fullmatch(RE_ARRAY_ITEM, '{ TYPE_HOTPLUG_HANDLER },')
    assert fullmatch(RE_ARRAY_ITEM, '{ TYPE_ACPI_DEVICE_IF },')
    assert fullmatch(RE_ARRAY_ITEM, '{ }')
    assert fullmatch(RE_ARRAY_CAST, '(InterfaceInfo[])')
    assert fullmatch(RE_ARRAY, '''(InterfaceInfo[]) {
            { TYPE_HOTPLUG_HANDLER },
            { TYPE_ACPI_DEVICE_IF },
            { }
    }''')
    print(RE_COMMENT)
    assert fullmatch(RE_COMMENT, r'''/* multi-line
                                      * comment
                                      */''')

    print(RE_TI_FIELDS)
    assert fullmatch(RE_TI_FIELDS,
    r'''/* could be TYPE_SYS_BUS_DEVICE (or LPC etc) */
        .parent = TYPE_DEVICE,
''')
    assert fullmatch(RE_TI_FIELDS, r'''.name = TYPE_TPM_CRB,
        /* could be TYPE_SYS_BUS_DEVICE (or LPC etc) */
        .parent = TYPE_DEVICE,
        .instance_size = sizeof(CRBState),
        .class_init  = tpm_crb_class_init,
        .interfaces = (InterfaceInfo[]) {
            { TYPE_TPM_IF },
            { }
        }
''')
    assert fullmatch(RE_TI_FIELDS + SP + RE_COMMENTS,
        r'''.name = TYPE_PALM_MISC_GPIO,
            .parent = TYPE_SYS_BUS_DEVICE,
            .instance_size = sizeof(PalmMiscGPIOState),
            .instance_init = palm_misc_gpio_init,
            /*
             * No class init required: device has no internal state so does not
             * need to set up reset or vmstate, and has no realize method.
             */''')

    print(TypeInfoVar.regexp)
    test_empty = 'static const TypeInfo x86_base_cpu_type_info = {\n'+\
                 '};\n';
    assert fullmatch(TypeInfoVar.regexp, test_empty)

    test_simple = r'''
    static const TypeInfo x86_base_cpu_type_info = {
        .name = X86_CPU_TYPE_NAME("base"),
        .parent = TYPE_X86_CPU,
        .class_init = x86_cpu_base_class_init,
    };
    '''
    assert re.search(TypeInfoVar.regexp, test_simple, re.MULTILINE)

    test_interfaces = r'''
    static const TypeInfo acpi_ged_info = {
        .name          = TYPE_ACPI_GED,
        .parent        = TYPE_SYS_BUS_DEVICE,
        .instance_size = sizeof(AcpiGedState),
        .instance_init  = acpi_ged_initfn,
        .class_init    = acpi_ged_class_init,
        .interfaces = (InterfaceInfo[]) {
            { TYPE_HOTPLUG_HANDLER },
            { TYPE_ACPI_DEVICE_IF },
            { }
        }
    };
    '''
    assert re.search(TypeInfoVar.regexp, test_interfaces, re.MULTILINE)

    test_comments = r'''
    static const TypeInfo palm_misc_gpio_info = {
        .name = TYPE_PALM_MISC_GPIO,
        .parent = TYPE_SYS_BUS_DEVICE,
        .instance_size = sizeof(PalmMiscGPIOState),
        .instance_init = palm_misc_gpio_init,
        /*
         * No class init required: device has no internal state so does not
         * need to set up reset or vmstate, and has no realize method.
         */
    };
    '''
    assert re.search(TypeInfoVar.regexp, test_comments, re.MULTILINE)

    test_comments = r'''
    static const TypeInfo tpm_crb_info = {
        .name = TYPE_TPM_CRB,
        /* could be TYPE_SYS_BUS_DEVICE (or LPC etc) */
        .parent = TYPE_DEVICE,
        .instance_size = sizeof(CRBState),
        .class_init  = tpm_crb_class_init,
        .interfaces = (InterfaceInfo[]) {
            { TYPE_TPM_IF },
            { }
        }
    };
    '''
    assert re.search(TypeInfoVar.regexp, test_comments, re.MULTILINE)

def test_struct_re():
    print('---')
    print(RE_STRUCT_TYPEDEF)
    assert re.search(RE_STRUCT_TYPEDEF, r'''
typedef struct TCGState {
    AccelState parent_obj;

    bool mttcg_enabled;
    unsigned long tb_size;
} TCGState;
''', re.MULTILINE)

    assert re.search(RE_STRUCT_TYPEDEF, r'''
typedef struct {
    ISADevice parent_obj;

    QEMUSoundCard card;
    uint32_t freq;
    uint32_t port;
    int ticking[2];
    int enabled;
    int active;
    int bufpos;
#ifdef DEBUG
    int64_t exp[2];
#endif
    int16_t *mixbuf;
    uint64_t dexp[2];
    SWVoiceOut *voice;
    int left, pos, samples;
    QEMUAudioTimeStamp ats;
    FM_OPL *opl;
    PortioList port_list;
} AdlibState;
''', re.MULTILINE)

    false_positive = r'''
typedef struct dma_pagetable_entry {
    int32_t frame;
    int32_t owner;
} A B C D E;
struct foo {
    int x;
} some_variable;
'''
    assert not re.search(RE_STRUCT_TYPEDEF, false_positive, re.MULTILINE)

def test_initial_includes():
    print(InitialIncludes.regexp)
    c = '''
#ifndef HW_FLASH_H
#define HW_FLASH_H

/* NOR flash devices */

#include "qom/object.h"
#include "exec/hwaddr.h"

/* pflash_cfi01.c */
'''
    print(repr(list(m.groupdict() for m in InitialIncludes.finditer(c))))
    m = InitialIncludes.domatch(c)
    assert m
    print(repr(m.group(0)))
    assert m.group(0).endswith('#include "exec/hwaddr.h"\n')

    c = '''#ifndef QEMU_VIRTIO_9P_H
#define QEMU_VIRTIO_9P_H

#include "standard-headers/linux/virtio_9p.h"
#include "hw/virtio/virtio.h"
#include "9p.h"


'''
    print(repr(list(m.groupdict() for m in InitialIncludes.finditer(c))))
    m = InitialIncludes.domatch(c)
    assert m
    print(repr(m.group(0)))
    assert m.group(0).endswith('#include "9p.h"\n')

    c = '''#include "qom/object.h"
/*
 * QEMU ES1370 emulation
...
 */

/* #define DEBUG_ES1370 */
/* #define VERBOSE_ES1370 */
#define SILENT_ES1370

#include "qemu/osdep.h"
#include "hw/audio/soundhw.h"
#include "audio/audio.h"
#include "hw/pci/pci.h"
#include "migration/vmstate.h"
#include "qemu/module.h"
#include "sysemu/dma.h"

/* Missing stuff:
   SCTRL_P[12](END|ST)INC
'''
    print(repr(list(m.groupdict() for m in InitialIncludes.finditer(c))))
    m = InitialIncludes.domatch(c)
    assert m
    print(repr(m.group(0)))
    assert m.group(0).endswith('#include "sysemu/dma.h"\n')

