__lazy_modules__ = [
    "argparse",
    "os",
    "pathlib",
    "_build",
    "_package",
    "_shared",
]

import argparse
import os
import pathlib

import _build
import _package
import _shared


def main():
    default_host_runner = (
        "{WASMTIME} run "
        # Set argv0 so that getpath.py can auto-discover the sysconfig data directory.
        "--argv0 {ARGV0} "
        # Map the checkout to / to load the stdlib from /Lib.
        "--dir {CHECKOUT}::/ "
        # Flags involving --optimize, --codegen, --debug, --wasm, and --wasi can be kept
        # in a config file.
        # We are using such a file to act as defaults in case a user wants to override
        # only some of the settings themselves, make it easy to modify settings
        # post-build so that they immediately apply to the Makefile instead of having to
        # regenerate it, and allow for easy copying of the settings for anyone else who
        # may want to use them.
        "--config {WASMTIME_CONFIG_PATH}"
    )
    context = _shared.Context()

    parser = argparse.ArgumentParser()
    subcommands = parser.add_subparsers(dest="subcommand")
    build = subcommands.add_parser("build", help="Build everything")
    configure_build = subcommands.add_parser(
        "configure-build-python", help="Run `configure` for the build Python"
    )
    make_build = subcommands.add_parser(
        "make-build-python", help="Run `make` for the build Python"
    )
    build_python = subcommands.add_parser(
        "build-python", help="Build the build Python"
    )
    pythoninfo_build = subcommands.add_parser(
        "pythoninfo-build", help="Display build info of the build Python"
    )
    configure_host = subcommands.add_parser(
        "configure-host",
        help="Run `configure` for the "
        "host/WASI (pydebug builds "
        "are inferred from the build "
        "Python)",
    )
    make_host = subcommands.add_parser(
        "make-host", help="Run `make` for the host/WASI"
    )
    build_host = subcommands.add_parser(
        "build-host", help="Build the host/WASI Python"
    )
    pythoninfo_host = subcommands.add_parser(
        "pythoninfo-host", help="Display build info of the host/WASI Python"
    )
    package = subcommands.add_parser(
        "package", help="Package the host/WASI Python into an archive"
    )
    subcommands.add_parser(
        "clean", help="Delete files and directories created by this script"
    )
    for subcommand in (
        build,
        configure_build,
        make_build,
        build_python,
        pythoninfo_build,
        configure_host,
        make_host,
        pythoninfo_host,
        build_host,
    ):
        subcommand.add_argument(
            "--quiet",
            action="store_true",
            default=False,
            dest="quiet",
            help="Redirect output from subprocesses to a log file",
        )
        subcommand.add_argument(
            "--logdir",
            type=pathlib.Path,
            default=None,
            dest="_log_path",
            metavar="LOG-DIR",
            help="Directory to store log files",
        )
    for subcommand in (
        configure_build,
        configure_host,
        build_python,
        build_host,
    ):
        subcommand.add_argument(
            "--clean",
            action="store_true",
            default=False,
            dest="clean",
            help="Delete any relevant directories before building",
        )
    for subcommand in (
        build,
        configure_build,
        configure_host,
        build_python,
        build_host,
    ):
        subcommand.add_argument(
            "args", nargs="*", help="Extra arguments to pass to `configure`"
        )
    for subcommand in build, configure_host, build_host:
        subcommand.add_argument(
            "--wasi-sdk",
            type=pathlib.Path,
            dest="_wasi_sdk_path",
            default=None,
            metavar="WASI-SDK-PATH",
            help="Path to the WASI SDK; defaults to WASI_SDK_PATH environment variable "
            "or the appropriate version found in /opt",
        )
        subcommand.add_argument(
            "--host-runner",
            action="store",
            default=default_host_runner,
            dest="host_runner",
            help="Command template for running the WASI host; defaults to "
            f"`{default_host_runner}`",
        )
    for subcommand in (
        build,
        configure_host,
        make_host,
        build_host,
        pythoninfo_host,
        package,
    ):
        subcommand.add_argument(
            "--host-triple",
            action="store",
            default=None,
            dest="_host_triple",
            metavar="WASI-TRIPLE",
            help="The target triple for the WASI host build; "
            f"defaults to the value found in {os.fsdecode(context.here / 'config.toml')}",
        )

    parser.parse_args(namespace=context)

    match context.subcommand:
        case "configure-build-python":
            _build.configure_build_python(context)
        case "make-build-python":
            _build.make_build_python(context)
        case "build-python":
            _build.configure_build_python(context)
            _build.make_build_python(context)
        case "pythoninfo-build":
            _build.pythoninfo_build_python(context)
        case "configure-host":
            _build.configure_wasi_python(context)
        case "make-host":
            _build.make_wasi_python(context)
        case "build-host":
            _build.configure_wasi_python(context)
            _build.make_wasi_python(context)
        case "pythoninfo-host":
            _build.pythoninfo_wasi_python(context)
        case "build":
            # Configure and build the build Python
            _build.configure_build_python(context)
            _build.make_build_python(context)
            if not context.quiet:
                _build.pythoninfo_build_python(context)

            # Configure and build the host/WASI Python
            _build.configure_wasi_python(context)
            _build.make_wasi_python(context)
            if not context.quiet:
                _build.pythoninfo_wasi_python(context)
        case "clean":
            _build.clean_contents(context)
        case "package":
            _package.gather(context)
            _package.archive(context)
        case None:
            parser.print_help()
        case _:
            raise ValueError(f"Unknown subcommand {context.subcommand!r}")


if __name__ == "__main__":
    main()
