# -*- 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.optional:
                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)


@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):
        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]] = {}
        self._main_module: Optional[str] = None

    @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]

    @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)
        self._module[name] = (genc, genh)
        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) in self._module.items():
            if QAPISchemaModule.is_builtin_module(name) and not opt_builtins:
                continue
            genc.write(output_dir)
            genh.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))
