# -*- Mode: Python -*-
# coding=utf-8

# GDBus - GLib D-Bus Library
#
# Copyright (C) 2008-2011 Red Hat, Inc.
# Copyright (C) 2018 Iñigo Martínez <inigomartinez@gmail.com>
#
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General
# Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
#
# Author: David Zeuthen <davidz@redhat.com>

import argparse
import os
import sys
from contextlib import contextmanager

from . import config
from . import dbustypes
from . import parser
from . import codegen
from . import codegen_docbook
from . import codegen_md
from . import codegen_rst
from .utils import print_error, print_warning


def find_arg(arg_list, arg_name):
    for a in arg_list:
        if a.name == arg_name:
            return a
    return None


def find_method(iface, method):
    for m in iface.methods:
        if m.name == method:
            return m
    return None


def find_signal(iface, signal):
    for m in iface.signals:
        if m.name == signal:
            return m
    return None


def find_prop(iface, prop):
    for m in iface.properties:
        if m.name == prop:
            return m
    return None


@contextmanager
def file_or_stdout(filename):
    if filename is None or filename == "-":
        yield sys.stdout
    else:
        with open(filename, "w") as outfile:
            yield outfile


def apply_annotation(iface_list, iface, method, signal, prop, arg, key, value):
    iface_obj = None
    for i in iface_list:
        if i.name == iface:
            iface_obj = i
            break

    if iface_obj is None:
        print_error('No interface "{}"'.format(iface))

    target_obj = None

    if method:
        method_obj = find_method(iface_obj, method)
        if method_obj is None:
            print_error('No method "{}" on interface "{}"'.format(method, iface))
        if arg:
            arg_obj = find_arg(method_obj.in_args, arg)
            if arg_obj is None:
                arg_obj = find_arg(method_obj.out_args, arg)
                if arg_obj is None:
                    print_error(
                        'No arg "{}" on method "{}" on interface "{}"'.format(
                            arg, method, iface
                        )
                    )
            target_obj = arg_obj
        else:
            target_obj = method_obj
    elif signal:
        signal_obj = find_signal(iface_obj, signal)
        if signal_obj is None:
            print_error('No signal "{}" on interface "{}"'.format(signal, iface))
        if arg:
            arg_obj = find_arg(signal_obj.args, arg)
            if arg_obj is None:
                print_error(
                    'No arg "{}" on signal "{}" on interface "{}"'.format(
                        arg, signal, iface
                    )
                )
            target_obj = arg_obj
        else:
            target_obj = signal_obj
    elif prop:
        prop_obj = find_prop(iface_obj, prop)
        if prop_obj is None:
            print_error('No property "{}" on interface "{}"'.format(prop, iface))
        target_obj = prop_obj
    else:
        target_obj = iface_obj
    target_obj.annotations.insert(0, dbustypes.Annotation(key, value))


def apply_annotations(iface_list, annotation_list):
    # apply annotations given on the command line
    for what, key, value in annotation_list:
        pos = what.find("::")
        if pos != -1:
            # signal
            iface = what[0:pos]
            signal = what[pos + 2 :]
            pos = signal.find("[")
            if pos != -1:
                arg = signal[pos + 1 :]
                signal = signal[0:pos]
                pos = arg.find("]")
                arg = arg[0:pos]
                apply_annotation(iface_list, iface, None, signal, None, arg, key, value)
            else:
                apply_annotation(
                    iface_list, iface, None, signal, None, None, key, value
                )
        else:
            pos = what.find(":")
            if pos != -1:
                # property
                iface = what[0:pos]
                prop = what[pos + 1 :]
                apply_annotation(iface_list, iface, None, None, prop, None, key, value)
            else:
                pos = what.find("()")
                if pos != -1:
                    # method
                    combined = what[0:pos]
                    pos = combined.rfind(".")
                    iface = combined[0:pos]
                    method = combined[pos + 1 :]
                    pos = what.find("[")
                    if pos != -1:
                        arg = what[pos + 1 :]
                        pos = arg.find("]")
                        arg = arg[0:pos]
                        apply_annotation(
                            iface_list, iface, method, None, None, arg, key, value
                        )
                    else:
                        apply_annotation(
                            iface_list, iface, method, None, None, None, key, value
                        )
                else:
                    # must be an interface
                    iface = what
                    apply_annotation(
                        iface_list, iface, None, None, None, None, key, value
                    )


def codegen_main():
    arg_parser = argparse.ArgumentParser(
        description="D-Bus code and documentation generator"
    )
    arg_parser.add_argument(
        "files", metavar="FILE", nargs="+", help="D-Bus introspection XML file"
    )
    arg_parser.add_argument(
        "--xml-files",
        metavar="FILE",
        action="append",
        default=[],
        help=argparse.SUPPRESS,
    )
    arg_parser.add_argument(
        "--interface-prefix",
        metavar="PREFIX",
        default="",
        help="String to strip from D-Bus interface names for code and docs",
    )
    arg_parser.add_argument(
        "--c-namespace",
        metavar="NAMESPACE",
        default="",
        help="The namespace to use for generated C code",
    )
    arg_parser.add_argument(
        "--c-generate-object-manager",
        action="store_true",
        help="Generate a GDBusObjectManagerClient subclass when generating C code",
    )
    arg_parser.add_argument(
        "--c-generate-autocleanup",
        choices=["none", "objects", "all"],
        default="objects",
        help="Generate autocleanup support",
    )
    arg_parser.add_argument(
        "--generate-docbook",
        metavar="OUTFILES",
        help="Generate Docbook in OUTFILES-org.Project.IFace.xml",
    )
    arg_parser.add_argument(
        "--generate-md",
        metavar="OUTFILES",
        help="Generate Markdown in OUTFILES-org.Project.IFace.md",
    )
    arg_parser.add_argument(
        "--generate-rst",
        metavar="OUTFILES",
        help="Generate reStructuredText in OUTFILES-org.Project.IFace.rst",
    )
    arg_parser.add_argument(
        "--pragma-once",
        action="store_true",
        help='Use "pragma once" as the inclusion guard',
    )
    arg_parser.add_argument(
        "--annotate",
        nargs=3,
        action="append",
        metavar="WHAT KEY VALUE",
        help="Add annotation (may be used several times)",
    )
    arg_parser.add_argument(
        "--glib-min-required",
        metavar="VERSION",
        help="Minimum version of GLib to be supported by the outputted code "
        "(default: 2.30)",
    )
    arg_parser.add_argument(
        "--glib-max-allowed",
        metavar="VERSION",
        help="Maximum version of GLib to be used by the outputted code "
        "(default: current GLib version)",
    )
    arg_parser.add_argument(
        "--symbol-decorator",
        help="Macro used to decorate a symbol in the outputted header, "
        "possibly to export symbols",
    )
    arg_parser.add_argument(
        "--symbol-decorator-header",
        help="Additional header required for decorator specified by "
        "--symbol-decorator",
    )
    arg_parser.add_argument(
        "--symbol-decorator-define",
        help="Additional define required for decorator specified by "
        "--symbol-decorator",
    )

    group = arg_parser.add_mutually_exclusive_group()
    group.add_argument(
        "--generate-c-code", metavar="OUTFILES", help="Generate C code in OUTFILES.[ch]"
    )
    group.add_argument("--header", action="store_true", help="Generate C headers")
    group.add_argument("--body", action="store_true", help="Generate C code")
    group.add_argument(
        "--interface-info-header",
        action="store_true",
        help="Generate GDBusInterfaceInfo C header",
    )
    group.add_argument(
        "--interface-info-body",
        action="store_true",
        help="Generate GDBusInterfaceInfo C code",
    )

    group = arg_parser.add_mutually_exclusive_group()
    group.add_argument(
        "--output", metavar="FILE", help="Write output into the specified file"
    )
    group.add_argument(
        "--output-directory",
        metavar="OUTDIR",
        default="",
        help="Location to output generated files",
    )

    args = arg_parser.parse_args()

    if len(args.xml_files) > 0:
        print_warning(
            'The "--xml-files" option is deprecated; use positional arguments instead'
        )

    if (
        args.generate_c_code is not None
        or args.generate_docbook is not None
        or args.generate_md is not None
        or args.generate_rst is not None
    ) and args.output is not None:
        print_error(
            "Using --generate-c-code or --generate-{docbook,md,rst} and "
            "--output at the same time is not allowed"
        )

    if args.generate_c_code:
        header_name = args.generate_c_code + ".h"
        h_file = os.path.join(args.output_directory, header_name)
        args.header = True
        c_file = os.path.join(args.output_directory, args.generate_c_code + ".c")
        args.body = True
    elif args.header:
        if args.output is None:
            print_error("Using --header requires --output")

        h_file = args.output
        header_name = os.path.basename(h_file)
    elif args.body:
        if args.output is None:
            print_error("Using --body requires --output")

        c_file = args.output

        if c_file == "-":
            header_name = ""
        else:
            header_name = os.path.splitext(os.path.basename(c_file))[0] + ".h"
    elif args.interface_info_header:
        if args.output is None:
            print_error("Using --interface-info-header requires --output")
        if args.c_generate_object_manager:
            print_error(
                "--c-generate-object-manager is incompatible with "
                "--interface-info-header"
            )

        h_file = args.output
        header_name = os.path.basename(h_file)
    elif args.interface_info_body:
        if args.output is None:
            print_error("Using --interface-info-body requires --output")
        if args.c_generate_object_manager:
            print_error(
                "--c-generate-object-manager is incompatible with "
                "--interface-info-body"
            )

        c_file = args.output

        if c_file == "-":
            header_name = ""
        else:
            header_name = os.path.splitext(os.path.basename(c_file))[0] + ".h"

    # Check the minimum GLib version. The minimum --glib-min-required is 2.30,
    # because that’s when gdbus-codegen was introduced. Support 1, 2 or 3
    # component versions, but ignore the micro component if it’s present.
    if args.glib_min_required:
        try:
            parts = args.glib_min_required.split(".", 3)
            glib_min_required = (int(parts[0]), int(parts[1] if len(parts) > 1 else 0))
            # Ignore micro component, but still validate it:
            _ = int(parts[2] if len(parts) > 2 else 0)  # noqa: F841
        except (ValueError, IndexError):
            print_error(
                "Unrecognized --glib-min-required string ‘{}’".format(
                    args.glib_min_required
                )
            )

        if glib_min_required < (2, 30):
            print_error(
                "Invalid --glib-min-required string ‘{}’: minimum "
                "version is 2.30".format(args.glib_min_required)
            )
    else:
        glib_min_required = (2, 30)

    # And the maximum GLib version.
    if args.glib_max_allowed:
        try:
            parts = args.glib_max_allowed.split(".", 3)
            glib_max_allowed = (int(parts[0]), int(parts[1] if len(parts) > 1 else 0))
            # Ignore micro component, but still validate it:
            _ = int(parts[2] if len(parts) > 2 else 0)  # noqa: F841
        except (ValueError, IndexError):
            print_error(
                "Unrecognized --glib-max-allowed string ‘{}’".format(
                    args.glib_max_allowed
                )
            )
    else:
        glib_max_allowed = (config.MAJOR_VERSION, config.MINOR_VERSION)

    # Only allow --symbol-decorator-define and --symbol-decorator-header if
    # --symbol-decorator is used
    if args.symbol_decorator is None:
        if args.symbol_decorator_header or args.symbol_decorator_define:
            print_error(
                "--symbol-decorator-define and --symbol-decorator-header must "
                "be used with --symbol-decorator"
            )

    # Round --glib-max-allowed up to the next stable release.
    glib_max_allowed = (
        glib_max_allowed[0],
        glib_max_allowed[1] + (glib_max_allowed[1] % 2),
    )

    if glib_max_allowed < glib_min_required:
        print_error(
            "Invalid versions: --glib-min-required ({}) must be "
            "less than or equal to --glib-max-allowed ({})".format(
                glib_min_required, glib_max_allowed
            )
        )

    all_ifaces = []
    input_files_basenames = []
    for fname in sorted(args.files + args.xml_files):
        with open(fname, "rb") as f:
            xml_data = f.read()
        parsed_ifaces = parser.parse_dbus_xml(
            xml_data, h_type_implies_unix_fd=(glib_min_required >= (2, 64))
        )
        all_ifaces.extend(parsed_ifaces)
        input_files_basenames.append(os.path.basename(fname))

    if args.annotate is not None:
        apply_annotations(all_ifaces, args.annotate)

    for i in all_ifaces:
        i.post_process(args.interface_prefix, args.c_namespace)

    docbook = args.generate_docbook
    docbook_gen = codegen_docbook.DocbookCodeGenerator(all_ifaces)
    if docbook:
        docbook_gen.generate(docbook, args.output_directory)

    md = args.generate_md
    md_gen = codegen_md.MdCodeGenerator(all_ifaces)
    if md:
        md_gen.generate(md, args.output_directory)

    rst = args.generate_rst
    rst_gen = codegen_rst.RstCodeGenerator(all_ifaces)
    if rst:
        rst_gen.generate(rst, args.output_directory)

    if args.header:
        with file_or_stdout(h_file) as outfile:
            gen = codegen.HeaderCodeGenerator(
                all_ifaces,
                args.c_namespace,
                args.c_generate_object_manager,
                args.c_generate_autocleanup,
                header_name,
                input_files_basenames,
                args.pragma_once,
                glib_min_required,
                args.symbol_decorator,
                args.symbol_decorator_header,
                outfile,
            )
            gen.generate()

    if args.body:
        with file_or_stdout(c_file) as outfile:
            gen = codegen.CodeGenerator(
                all_ifaces,
                args.c_namespace,
                args.c_generate_object_manager,
                header_name,
                input_files_basenames,
                docbook_gen,
                glib_min_required,
                args.symbol_decorator_define,
                outfile,
            )
            gen.generate()

    if args.interface_info_header:
        with file_or_stdout(h_file) as outfile:
            gen = codegen.InterfaceInfoHeaderCodeGenerator(
                all_ifaces,
                args.c_namespace,
                header_name,
                input_files_basenames,
                args.pragma_once,
                glib_min_required,
                args.symbol_decorator,
                args.symbol_decorator_header,
                outfile,
            )
            gen.generate()

    if args.interface_info_body:
        with file_or_stdout(c_file) as outfile:
            gen = codegen.InterfaceInfoBodyCodeGenerator(
                all_ifaces,
                args.c_namespace,
                header_name,
                input_files_basenames,
                glib_min_required,
                args.symbol_decorator_define,
                outfile,
            )
            gen.generate()

    sys.exit(0)


if __name__ == "__main__":
    codegen_main()
