# This work is licensed under the terms of the GNU GPL, version 2 or later.
# See the COPYING file in the top-level directory.

"""
QAPI Generator

This is the main entry point for generating C code from the QAPI schema.
"""

import argparse
import sys
from typing import Optional

from .commands import gen_commands
from .common import must_match
from .error import QAPIError
from .events import gen_events
from .introspect import gen_introspect
from .schema import QAPISchema
from .types import gen_types
from .visit import gen_visit


def invalid_prefix_char(prefix: str) -> Optional[str]:
    match = must_match(r'([A-Za-z_.-][A-Za-z0-9_.-]*)?', prefix)
    if match.end() != len(prefix):
        return prefix[match.end()]
    return None


def generate(schema_file: str,
             output_dir: str,
             prefix: str,
             unmask: bool = False,
             builtins: bool = False) -> None:
    """
    Generate C code for the given schema into the target directory.

    :param schema_file: The primary QAPI schema file.
    :param output_dir: The output directory to store generated code.
    :param prefix: Optional C-code prefix for symbol names.
    :param unmask: Expose non-ABI names through introspection?
    :param builtins: Generate code for built-in types?

    :raise QAPIError: On failures.
    """
    assert invalid_prefix_char(prefix) is None

    schema = QAPISchema(schema_file)
    gen_types(schema, output_dir, prefix, builtins)
    gen_visit(schema, output_dir, prefix, builtins)
    gen_commands(schema, output_dir, prefix)
    gen_events(schema, output_dir, prefix)
    gen_introspect(schema, output_dir, prefix, unmask)


def main() -> int:
    """
    gapi-gen executable entry point.
    Expects arguments via sys.argv, see --help for details.

    :return: int, 0 on success, 1 on failure.
    """
    parser = argparse.ArgumentParser(
        description='Generate code from a QAPI schema')
    parser.add_argument('-b', '--builtins', action='store_true',
                        help="generate code for built-in types")
    parser.add_argument('-o', '--output-dir', action='store',
                        default='',
                        help="write output to directory OUTPUT_DIR")
    parser.add_argument('-p', '--prefix', action='store',
                        default='',
                        help="prefix for symbols")
    parser.add_argument('-u', '--unmask-non-abi-names', action='store_true',
                        dest='unmask',
                        help="expose non-ABI names in introspection")
    parser.add_argument('schema', action='store')
    args = parser.parse_args()

    funny_char = invalid_prefix_char(args.prefix)
    if funny_char:
        msg = f"funny character '{funny_char}' in argument of --prefix"
        print(f"{sys.argv[0]}: {msg}", file=sys.stderr)
        return 1

    try:
        generate(args.schema,
                 output_dir=args.output_dir,
                 prefix=args.prefix,
                 unmask=args.unmask,
                 builtins=args.builtins)
    except QAPIError as err:
        print(f"{sys.argv[0]}: {str(err)}", file=sys.stderr)
        return 1
    return 0
