#!/usr/bin/env python
"""
Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
See https://llvm.org/LICENSE.txt for license information.
SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

Prepares language bindings for LLDB build process.  Run with --help
to see a description of the supported command line arguments.
"""

# Python modules:
import argparse
import logging
import os
import platform
import sys

# LLDB modules:
import use_lldb_suite
from lldbsuite.support import fs


def prepare_binding_for_language(scripts_dir, script_lang, options):
    """Prepares the binding for a specific language.

    @param scripts_dir the full path to the scripts source directory.
    @param script_lang the name of the script language.  Should be a child
    directory within the scripts dir, and should contain a
    prepare_scripts_{script_lang}.py script file in it.
    @param options the dictionary of parsed command line options.

    There is no return value.  If it returns, the process succeeded; otherwise,
    the process will exit where it fails.
    """
    # Ensure the language-specific prepare module exists.
    script_name = "prepare_binding_{}.py".format(script_lang)
    lang_path = os.path.join(scripts_dir, script_lang)
    script_path = os.path.join(lang_path, script_name)
    if not os.path.exists(script_path):
        logging.error(
            "failed to find prepare script for language '%s' at '%s'",
            script_lang,
            script_path)
        sys.exit(-9)

    # Include this language-specific directory in the Python search
    # path.
    sys.path.append(os.path.normcase(lang_path))

    # Execute the specific language script
    module_name = os.path.splitext(script_name)[0]
    module = __import__(module_name)
    module.main(options)

    # Remove the language-specific directory from the Python search path.
    sys.path.remove(os.path.normcase(lang_path))


def prepare_all_bindings(options):
    """Prepares bindings for each of the languages supported.

    @param options the parsed arguments from the command line

    @return the exit value for the program. 0 is success, all othes
    indicate some kind of failure.
    """
    # Check for the existence of the SWIG scripts folder
    scripts_dir = os.path.join(options.src_root, "scripts")
    if not os.path.exists(scripts_dir):
        logging.error("failed to find scripts dir: '%s'", scripts_dir)
        sys.exit(-8)

    child_dirs = ["Python"]

    # Iterate script directory find any script language directories
    for script_lang in child_dirs:
        logging.info("executing language script for: '%s'", script_lang)
        prepare_binding_for_language(scripts_dir, script_lang, options)


def process_args(args):
    """Returns options processed from the provided command line.

    @param args the command line to process.
    """

    # Setup the parser arguments that are accepted.
    parser = argparse.ArgumentParser(
        description="Prepare language bindings for LLDB build.")

    # Arguments to control logging verbosity.
    parser.add_argument(
        "--debug", "-d",
        action="store_true",
        help="Set program logging level to DEBUG.")
    parser.add_argument(
        "--verbose", "-v",
        action="count",
        default=0,
        help=(
            "Increase logging verbosity level.  Default: only error and "
            "higher are displayed.  Each -v increases level of verbosity."))

    # Arguments to control whether we're building an OS X-style
    # framework.  This is the opposite of the older "-m" (makefile)
    # option.
    parser.add_argument(
        "--config-build-dir",
        "--cfgBldDir",
        help=(
            "Configuration build dir, will use python module path "
            "if unspecified."))
    parser.add_argument(
        "--find-swig",
        action="store_true",
        help=(
            "Indicates the swig executable should be searched for "
            "if not eplicitly provided.  Either this or the explicit "
            "swig executable option must be provided."))
    parser.add_argument(
        "--framework",
        action="store_true",
        help="Prepare as OS X-style framework.")
    parser.add_argument(
        "--generate-dependency-file",
        "-M",
        action="store_true",
        help="Make the dependency (.d) file for the wrappers.")
    parser.add_argument(
        "--prefix",
        help="Override path where the LLDB module is placed.")
    parser.add_argument(
        "--src-root",
        "--srcRoot",
        "-s",
        # Default to the parent directory of this script's directory.
        default=os.path.abspath(
            os.path.join(
                os.path.dirname(os.path.realpath(__file__)),
                os.path.pardir)),
        help="Specifies the LLDB source root directory.")
    parser.add_argument(
        "--swig-executable",
        "--swigExecutable",
        help="Path to the swig executable.")
    parser.add_argument(
        "--target-dir",
        "--targetDir",
        required=True,
        help=(
            "Specifies the build dir where the language binding "
            "should be placed"))

    parser.add_argument(
        "--target-platform",
        help=(
            "Specifies the platform we are building for."
            "Should be the same as what platform.system() returns."))
    # Process args.
    options = parser.parse_args(args)

    # Set logging level based on verbosity count.
    if options.debug:
        log_level = logging.DEBUG
    else:
        # See logging documentation for error levels.  We'll default
        # to showing ERROR or higher error messages.  For each -v
        # specified, we'll shift to the next lower-priority log level.
        log_level = logging.ERROR - 10 * options.verbose
        if log_level < logging.NOTSET:
            # Displays all logged messages.
            log_level = logging.NOTSET
    logging.basicConfig(level=log_level)
    logging.info("logging is using level: %d", log_level)

    return options


def main(args):
    """Drives the main script preparation steps.

    @param args list of command line arguments.
    """
    # Process command line arguments.
    options = process_args(args)
    logging.debug("Processed args: options=%s", options)

    # Ensure we have a swig executable.
    if not options.swig_executable or len(options.swig_executable) == 0:
        if options.find_swig:
            try:
                options.swig_executable = fs.find_executable("swig")
            except Exception as e:
                logging.error("Unable to find swig executable: %s" % e.message)
                sys.exit(-6)
        else:
            logging.error(
                "The --find-swig option must be specified "
                "when the swig executable location is not "
                "explicitly provided.")
            sys.exit(-12)

    # Check if the swig file exists.
    swig_path = os.path.normcase(
        os.path.join(options.src_root, "scripts", "lldb.swig"))
    if not os.path.isfile(swig_path):
        logging.error("swig file not found at '%s'", swig_path)
        sys.exit(-3)

    # Prepare bindings for each supported language binding.
    # This will error out if it doesn't succeed.
    prepare_all_bindings(options)
    sys.exit(0)

if __name__ == "__main__":
    # Run the main driver loop.
    main(sys.argv[1:])
