# Copyright 2015 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Collection of tools to create sysroots."""

import sys

from chromite.lib import commandline
from chromite.lib import cros_build_lib
from chromite.lib import osutils
from chromite.lib import sysroot_lib


def ParseArgs(argv):
    """Parse arguments.

    Args:
      argv: array of arguments passed to the script.
    """
    parser = commandline.ArgumentParser(description=__doc__)
    parser.set_defaults(out_file=None)
    subparser = parser.add_subparsers()
    wrapper = subparser.add_parser("create-wrappers")
    wrapper.add_argument(
        "--sysroot", help="Path to the sysroot.", required=True
    )
    wrapper.add_argument(
        "--friendlyname", help="Name to append to the commands."
    )
    wrapper.set_defaults(command="create-wrappers")

    config = subparser.add_parser("generate-config")
    target = config.add_mutually_exclusive_group(required=True)
    target.add_argument("--board", help="Board to generate the config for.")
    config.add_argument(
        "--out-file",
        dest="out_file",
        help="File to write into. If not specified, the "
        "configuration will be printed to stdout.",
    )
    config.add_argument("--sysroot", help="Path to the sysroot.", required=True)
    config.set_defaults(command="generate-config")

    makeconf = subparser.add_parser("generate-make-conf")
    makeconf.add_argument("--sysroot", help="Sysroot to use.")
    makeconf.add_argument(
        "--out-file",
        dest="out_file",
        help="File to write the configuration into. If not "
        "specified, the configuration will be printed to "
        "stdout.",
    )
    makeconf.add_argument(
        "--accepted-licenses", help="List of accepted licenses."
    )
    makeconf.set_defaults(command="generate-make-conf")

    binhost = subparser.add_parser("generate-binhosts")
    binhost.add_argument("--sysroot", help="Sysroot to use.")
    binhost.add_argument(
        "--out-file",
        dest="out_file",
        help="File to write the configuration into. If not "
        "specified, the configuration will be printed to "
        "stdout.",
    )
    binhost.add_argument(
        "--local-only",
        dest="local_only",
        action="store_true",
        help="Use compatible local boards only.",
    )
    binhost.set_defaults(command="generate-binhosts")

    options = parser.parse_args(argv)
    options.Freeze()
    return options


def main(argv):
    opts = ParseArgs(argv)
    if not cros_build_lib.IsInsideChroot():
        raise commandline.ChrootRequiredError(argv)

    if osutils.IsNonRootUser():
        cros_build_lib.sudo_run(sys.argv, print_cmd=False)
        return

    # This short script is using |output| for the whole duration, thus we are
    # not concerned with leaking it, and `with` is awkward to use with
    # sys.stdout.
    # pylint: disable=consider-using-with
    output = sys.stdout
    if opts.out_file:
        output = open(opts.out_file, "w", encoding="utf-8")

    sysroot = sysroot_lib.Sysroot(opts.sysroot)
    if opts.command == "create-wrappers":
        sysroot.CreateAllWrappers(opts.friendlyname)
    elif opts.command == "generate-config":
        output.write("\n" + sysroot.GenerateBoardSetupConfig(opts.board))
    elif opts.command == "generate-make-conf":
        output.write(
            "\n" + sysroot.GenerateBoardMakeConf(opts.accepted_licenses)
        )
    elif opts.command == "generate-binhosts":
        output.write("\n" + sysroot.GenerateBinhostConf(opts.local_only))
