# -*- coding: utf-8 -*-
#
# QAPI code generation
#
# Copyright (c) 2015-2019 Red Hat Inc.
#
# Authors:
#  Markus Armbruster <armbru@redhat.com>
#  Marc-André Lureau <marcandre.lureau@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 contextlib import contextmanager
import os
import re
from typing import (
    Dict,
    Iterator,
    Optional,
    Sequence,
    Tuple,
)

from .common import (
    c_fname,
    c_name,
    guardend,
    guardstart,
    mcgen,
)
from .schema import (
    QAPISchemaFeature,
    QAPISchemaIfCond,
    QAPISchemaModule,
    QAPISchemaObjectType,
    QAPISchemaVisitor,
)
from .source import QAPISourceInfo


def gen_special_features(features: Sequence[QAPISchemaFeature]) -> str:
    special_features = [f"1u << QAPI_{feat.name.upper()}"
                        for feat in features if feat.is_special()]
    return ' | '.join(special_features) or '0'


class QAPIGen:
    def __init__(self, fname: str):
        self.fname = fname
        self._preamble = ''
        self._body = ''

    def preamble_add(self, text: str) -> None:
        self._preamble += text

    def add(self, text: str) -> None:
        self._body += text

    def get_content(self) -> str:
        return self._top() + self._preamble + self._body + self._bottom()

    def _top(self) -> str:
        # pylint: disable=no-self-use
        return ''

    def _bottom(self) -> str:
        # pylint: disable=no-self-use
        return ''

    def write(self, output_dir: str) -> None:
        # Include paths starting with ../ are used to reuse modules of the main
        # schema in specialised schemas. Don't overwrite the files that are
        # already generated for the main schema.
        if self.fname.startswith('../'):
            return
        pathname = os.path.join(output_dir, self.fname)
        odir = os.path.dirname(pathname)

        if odir:
            os.makedirs(odir, exist_ok=True)

        # use os.open for O_CREAT to create and read a non-existant file
        fd = os.open(pathname, os.O_RDWR | os.O_CREAT, 0o666)
        with os.fdopen(fd, 'r+', encoding='utf-8') as fp:
            text = self.get_content()
            oldtext = fp.read(len(text) + 1)
            if text != oldtext:
                fp.seek(0)
                fp.truncate(0)
                fp.write(text)


def _wrap_ifcond(ifcond: QAPISchemaIfCond, before: str, after: str) -> str:
    if before == after:
        return after   # suppress empty #if ... #endif

    assert after.startswith(before)
    out = before
    added = after[len(before):]
    if added[0] == '\n':
        out += '\n'
        added = added[1:]
    out += ifcond.gen_if()
    out += added
    out += ifcond.gen_endif()
    return out


def build_params(arg_type: Optional[QAPISchemaObjectType],
                 boxed: bool,
                 extra: Optional[str] = None) -> str:
    ret = ''
    sep = ''
    if boxed:
        assert arg_type
        ret += '%s arg' % arg_type.c_param_type()
        sep = ', '
    elif arg_type:
        assert not arg_type.variants
        for memb in arg_type.members:
            ret += sep
            sep = ', '
            if memb.need_has():
                ret += 'bool has_%s, ' % c_name(memb.name)
            ret += '%s %s' % (memb.type.c_param_type(),
                              c_name(memb.name))
    if extra:
        ret += sep + extra
    return ret if ret else 'void'


class QAPIGenCCode(QAPIGen):
    def __init__(self, fname: str):
        super().__init__(fname)
        self._start_if: Optional[Tuple[QAPISchemaIfCond, str, str]] = None

    def start_if(self, ifcond: QAPISchemaIfCond) -> None:
        assert self._start_if is None
        self._start_if = (ifcond, self._body, self._preamble)

    def end_if(self) -> None:
        assert self._start_if is not None
        self._body = _wrap_ifcond(self._start_if[0],
                                  self._start_if[1], self._body)
        self._preamble = _wrap_ifcond(self._start_if[0],
                                      self._start_if[2], self._preamble)
        self._start_if = None

    def get_content(self) -> str:
        assert self._start_if is None
        return super().get_content()


class QAPIGenC(QAPIGenCCode):
    def __init__(self, fname: str, blurb: str, pydoc: str):
        super().__init__(fname)
        self._blurb = blurb
        self._copyright = '\n * '.join(re.findall(r'^Copyright .*', pydoc,
                                                  re.MULTILINE))

    def _top(self) -> str:
        return mcgen('''
/* AUTOMATICALLY GENERATED, DO NOT MODIFY */

/*
%(blurb)s
 *
 * %(copyright)s
 *
 * 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.
 */

''',
                     blurb=self._blurb, copyright=self._copyright)

    def _bottom(self) -> str:
        return mcgen('''

/* Dummy declaration to prevent empty .o file */
char qapi_dummy_%(name)s;
''',
                     name=c_fname(self.fname))


class QAPIGenH(QAPIGenC):
    def _top(self) -> str:
        return super()._top() + guardstart(self.fname)

    def _bottom(self) -> str:
        return guardend(self.fname)


class QAPIGenTrace(QAPIGen):
    def _top(self) -> str:
        return super()._top() + '# AUTOMATICALLY GENERATED, DO NOT MODIFY\n\n'


@contextmanager
def ifcontext(ifcond: QAPISchemaIfCond, *args: QAPIGenCCode) -> Iterator[None]:
    """
    A with-statement context manager that wraps with `start_if()` / `end_if()`.

    :param ifcond: A sequence of conditionals, passed to `start_if()`.
    :param args: any number of `QAPIGenCCode`.

    Example::

        with ifcontext(ifcond, self._genh, self._genc):
            modify self._genh and self._genc ...

    Is equivalent to calling::

        self._genh.start_if(ifcond)
        self._genc.start_if(ifcond)
        modify self._genh and self._genc ...
        self._genh.end_if()
        self._genc.end_if()
    """
    for arg in args:
        arg.start_if(ifcond)
    yield
    for arg in args:
        arg.end_if()


class QAPISchemaMonolithicCVisitor(QAPISchemaVisitor):
    def __init__(self,
                 prefix: str,
                 what: str,
                 blurb: str,
                 pydoc: str):
        self._prefix = prefix
        self._what = what
        self._genc = QAPIGenC(self._prefix + self._what + '.c',
                              blurb, pydoc)
        self._genh = QAPIGenH(self._prefix + self._what + '.h',
                              blurb, pydoc)

    def write(self, output_dir: str) -> None:
        self._genc.write(output_dir)
        self._genh.write(output_dir)


class QAPISchemaModularCVisitor(QAPISchemaVisitor):
    def __init__(self,
                 prefix: str,
                 what: str,
                 user_blurb: str,
                 builtin_blurb: Optional[str],
                 pydoc: str,
                 gen_tracing: bool = False):
        self._prefix = prefix
        self._what = what
        self._user_blurb = user_blurb
        self._builtin_blurb = builtin_blurb
        self._pydoc = pydoc
        self._current_module: Optional[str] = None
        self._module: Dict[str, Tuple[QAPIGenC, QAPIGenH,
                                      Optional[QAPIGenTrace]]] = {}
        self._main_module: Optional[str] = None
        self._gen_tracing = gen_tracing

    @property
    def _genc(self) -> QAPIGenC:
        assert self._current_module is not None
        return self._module[self._current_module][0]

    @property
    def _genh(self) -> QAPIGenH:
        assert self._current_module is not None
        return self._module[self._current_module][1]

    @property
    def _gen_trace_events(self) -> QAPIGenTrace:
        assert self._gen_tracing
        assert self._current_module is not None
        gent = self._module[self._current_module][2]
        assert gent is not None
        return gent

    @staticmethod
    def _module_dirname(name: str) -> str:
        if QAPISchemaModule.is_user_module(name):
            return os.path.dirname(name)
        return ''

    def _module_basename(self, what: str, name: str) -> str:
        ret = '' if QAPISchemaModule.is_builtin_module(name) else self._prefix
        if QAPISchemaModule.is_user_module(name):
            basename = os.path.basename(name)
            ret += what
            if name != self._main_module:
                ret += '-' + os.path.splitext(basename)[0]
        else:
            assert QAPISchemaModule.is_system_module(name)
            ret += re.sub(r'-', '-' + name[2:] + '-', what)
        return ret

    def _module_filename(self, what: str, name: str) -> str:
        return os.path.join(self._module_dirname(name),
                            self._module_basename(what, name))

    def _add_module(self, name: str, blurb: str) -> None:
        if QAPISchemaModule.is_user_module(name):
            if self._main_module is None:
                self._main_module = name
        basename = self._module_filename(self._what, name)
        genc = QAPIGenC(basename + '.c', blurb, self._pydoc)
        genh = QAPIGenH(basename + '.h', blurb, self._pydoc)

        gent: Optional[QAPIGenTrace] = None
        if self._gen_tracing:
            gent = QAPIGenTrace(basename + '.trace-events')

        self._module[name] = (genc, genh, gent)
        self._current_module = name

    @contextmanager
    def _temp_module(self, name: str) -> Iterator[None]:
        old_module = self._current_module
        self._current_module = name
        yield
        self._current_module = old_module

    def write(self, output_dir: str, opt_builtins: bool = False) -> None:
        for name, (genc, genh, gent) in self._module.items():
            if QAPISchemaModule.is_builtin_module(name) and not opt_builtins:
                continue
            genc.write(output_dir)
            genh.write(output_dir)
            if gent is not None:
                gent.write(output_dir)

    def _begin_builtin_module(self) -> None:
        pass

    def _begin_user_module(self, name: str) -> None:
        pass

    def visit_module(self, name: str) -> None:
        if QAPISchemaModule.is_builtin_module(name):
            if self._builtin_blurb:
                self._add_module(name, self._builtin_blurb)
                self._begin_builtin_module()
            else:
                # The built-in module has not been created.  No code may
                # be generated.
                self._current_module = None
        else:
            assert QAPISchemaModule.is_user_module(name)
            self._add_module(name, self._user_blurb)
            self._begin_user_module(name)

    def visit_include(self, name: str, info: Optional[QAPISourceInfo]) -> None:
        relname = os.path.relpath(self._module_filename(self._what, name),
                                  os.path.dirname(self._genh.fname))
        self._genh.preamble_add(mcgen('''
#include "%(relname)s.h"
''',
                                      relname=relname))
