#! /usr/bin/env python3
"""Generate coroutine wrappers for block subsystem.

The program parses one or several concatenated c files from stdin,
searches for functions with the 'co_wrapper' specifier
and generates corresponding wrappers on stdout.

Usage: block-coroutine-wrapper.py generated-file.c FILE.[ch]...

Copyright (c) 2020 Virtuozzo International GmbH.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
"""

import sys
import re
from typing import Iterator


def gen_header():
    copyright = re.sub('^.*Copyright', 'Copyright', __doc__, flags=re.DOTALL)
    copyright = re.sub('^(?=.)', ' * ', copyright.strip(), flags=re.MULTILINE)
    copyright = re.sub('^$', ' *', copyright, flags=re.MULTILINE)
    return f"""\
/*
 * File is generated by scripts/block-coroutine-wrapper.py
 *
{copyright}
 */

#include "qemu/osdep.h"
#include "block/coroutines.h"
#include "block/block-gen.h"
#include "block/block_int.h"
#include "block/dirty-bitmap.h"
"""


class ParamDecl:
    param_re = re.compile(r'(?P<decl>'
                          r'(?P<type>.*[ *])'
                          r'(?P<name>[a-z][a-z0-9_]*)'
                          r')')

    def __init__(self, param_decl: str) -> None:
        m = self.param_re.match(param_decl.strip())
        if m is None:
            raise ValueError(f'Wrong parameter declaration: "{param_decl}"')
        self.decl = m.group('decl')
        self.type = m.group('type')
        self.name = m.group('name')


class FuncDecl:
    def __init__(self, return_type: str, name: str, args: str,
                 variant: str) -> None:
        self.return_type = return_type.strip()
        self.name = name.strip()
        self.struct_name = snake_to_camel(self.name)
        self.args = [ParamDecl(arg.strip()) for arg in args.split(',')]
        self.create_only_co = 'mixed' not in variant
        self.graph_rdlock = 'bdrv_rdlock' in variant

        subsystem, subname = self.name.split('_', 1)
        self.co_name = f'{subsystem}_co_{subname}'

        t = self.args[0].type
        if t == 'BlockDriverState *':
            ctx = 'bdrv_get_aio_context(bs)'
        elif t == 'BdrvChild *':
            ctx = 'bdrv_get_aio_context(child->bs)'
        elif t == 'BlockBackend *':
            ctx = 'blk_get_aio_context(blk)'
        else:
            ctx = 'qemu_get_aio_context()'
        self.ctx = ctx

    def gen_list(self, format: str) -> str:
        return ', '.join(format.format_map(arg.__dict__) for arg in self.args)

    def gen_block(self, format: str) -> str:
        return '\n'.join(format.format_map(arg.__dict__) for arg in self.args)


# Match wrappers declared with a co_wrapper mark
func_decl_re = re.compile(r'^(?P<return_type>[a-zA-Z][a-zA-Z0-9_]* [\*]?)'
                          r'\s*co_wrapper'
                          r'(?P<variant>(_[a-z][a-z0-9_]*)?)\s*'
                          r'(?P<wrapper_name>[a-z][a-z0-9_]*)'
                          r'\((?P<args>[^)]*)\);$', re.MULTILINE)


def func_decl_iter(text: str) -> Iterator:
    for m in func_decl_re.finditer(text):
        yield FuncDecl(return_type=m.group('return_type'),
                       name=m.group('wrapper_name'),
                       args=m.group('args'),
                       variant=m.group('variant'))


def snake_to_camel(func_name: str) -> str:
    """
    Convert underscore names like 'some_function_name' to camel-case like
    'SomeFunctionName'
    """
    words = func_name.split('_')
    words = [w[0].upper() + w[1:] for w in words]
    return ''.join(words)


def create_mixed_wrapper(func: FuncDecl) -> str:
    """
    Checks if we are already in coroutine
    """
    name = func.co_name
    struct_name = func.struct_name
    graph_assume_lock = 'assume_graph_lock();' if func.graph_rdlock else ''

    return f"""\
{func.return_type} {func.name}({ func.gen_list('{decl}') })
{{
    if (qemu_in_coroutine()) {{
        {graph_assume_lock}
        return {name}({ func.gen_list('{name}') });
    }} else {{
        {struct_name} s = {{
            .poll_state.ctx = {func.ctx},
            .poll_state.in_progress = true,

{ func.gen_block('            .{name} = {name},') }
        }};

        s.poll_state.co = qemu_coroutine_create({name}_entry, &s);

        bdrv_poll_co(&s.poll_state);
        return s.ret;
    }}
}}"""


def create_co_wrapper(func: FuncDecl) -> str:
    """
    Assumes we are not in coroutine, and creates one
    """
    name = func.co_name
    struct_name = func.struct_name
    return f"""\
{func.return_type} {func.name}({ func.gen_list('{decl}') })
{{
    {struct_name} s = {{
        .poll_state.ctx = {func.ctx},
        .poll_state.in_progress = true,

{ func.gen_block('        .{name} = {name},') }
    }};
    assert(!qemu_in_coroutine());

    s.poll_state.co = qemu_coroutine_create({name}_entry, &s);

    bdrv_poll_co(&s.poll_state);
    return s.ret;
}}"""


def gen_wrapper(func: FuncDecl) -> str:
    assert not '_co_' in func.name

    name = func.co_name
    struct_name = func.struct_name

    graph_lock=''
    graph_unlock=''
    if func.graph_rdlock:
        graph_lock='    bdrv_graph_co_rdlock();'
        graph_unlock='    bdrv_graph_co_rdunlock();'

    creation_function = create_mixed_wrapper
    if func.create_only_co:
        creation_function = create_co_wrapper

    return f"""\
/*
 * Wrappers for {name}
 */

typedef struct {struct_name} {{
    BdrvPollCo poll_state;
    {func.return_type} ret;
{ func.gen_block('    {decl};') }
}} {struct_name};

static void coroutine_fn {name}_entry(void *opaque)
{{
    {struct_name} *s = opaque;

{graph_lock}
    s->ret = {name}({ func.gen_list('s->{name}') });
{graph_unlock}
    s->poll_state.in_progress = false;

    aio_wait_kick();
}}

{creation_function(func)}"""


def gen_wrappers(input_code: str) -> str:
    res = ''
    for func in func_decl_iter(input_code):
        res += '\n\n\n'
        res += gen_wrapper(func)

    return res


if __name__ == '__main__':
    if len(sys.argv) < 3:
        exit(f'Usage: {sys.argv[0]} OUT_FILE.c IN_FILE.[ch]...')

    with open(sys.argv[1], 'w', encoding='utf-8') as f_out:
        f_out.write(gen_header())
        for fname in sys.argv[2:]:
            with open(fname, encoding='utf-8') as f_in:
                f_out.write(gen_wrappers(f_in.read()))
                f_out.write('\n')
