# -*- 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 sys
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:
            assert not memb.ifcond.is_present()
            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 by %(tool)s 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.
 */

''',
                     tool=os.path.basename(sys.argv[0]),
                     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 by '
                + os.path.basename(sys.argv[0])
                + ', 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))
