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

"""This script provides CLI access to run security tests on a Chrome OS images.

The entry point is available as image_lib.SecurityTest. Call that directly when
possible.

Note: You probably will need an internal checkout by default for these
      tests to be useful. You can provide your own baselines, but you
      can certainly provide your own set of configs.

Note: These tests will fail on dev images. They are designed to
      check release recovery images only.

Note: The --image argument can be a path or a basename. When a basename is
      provided, the --board argument is always used to build the path.
      Consequently, `./image_name.bin` and `image_name.bin` are treated
      very differently.
"""

import re

from chromite.lib import commandline
from chromite.lib import cros_build_lib
from chromite.lib import image_lib


def GetParser():
    """Build the Argument Parser."""
    parser = commandline.ArgumentParser(description=__doc__)

    parser.add_argument("--board", help="The board to test an image for.")
    # Avoiding type='path' to allow the use of `./` to distinguish between a
    # local image (e.g. `./image_name.bin`) and a basename (`image_name.bin`) in
    # the board's build directory. The `./` would be normalized out of a
    # type='path' argument, making it look like it's a basename.
    parser.add_argument(
        "--image",
        help="Source release image to use (recovery_image.bin by "
        "default). May be a path to an image or just the "
        "basename of the image if a board is also provided.",
    )
    parser.add_argument(
        "--baselines",
        type="str_path",
        help="Directory to load security baselines from (default "
        "from cros-signing).",
    )
    parser.add_argument(
        "--vboot-hash",
        help="The git rev of the vboot tree to checkout (default "
        "to the signer hash).",
    )

    return parser


def _ParseArgs(argv):
    """Parse and validate arguments."""
    parser = GetParser()
    opts = parser.parse_args(argv)

    # Need the board if no image provided or only the basename is provided so
    # we can build out the full path to an image file.
    opts.board = opts.board or cros_build_lib.GetDefaultBoard()
    try:
        opts.image = image_lib.BuildImagePath(opts.board, opts.image)
    except image_lib.ImageDoesNotExistError as e:
        # Replace |arg| with --arg, otherwise messages still relevant.
        message = re.sub(r"\|(\w+)\|", r"--\1", str(e))
        parser.error(message)

    opts.Freeze()
    return opts


def main(argv):
    cros_build_lib.AssertInsideChroot()
    opts = _ParseArgs(argv)
    try:
        success = image_lib.SecurityTest(
            board=opts.board,
            image=opts.image,
            baselines=opts.baselines,
            vboot_hash=opts.vboot_hash,
        )
    except image_lib.Error as e:
        cros_build_lib.Die(e)
    else:
        return 0 if success else 1
