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

"""Generate minidump symbols for use by the Crash server.

This script takes debug packages generated by the Borealis Arch build and
converts them to breakpad format.

The debug packages from Arch are generated by adding "options=(debug strip)"
to the PKGBUILD file.  The resulting archive contains:
- split .debug files in usr/lib/debug with a normal filesystem layout
- optional source files in usr/src/debug which will be ignored
- optional text metadata files (eg .PKGINFO, .BUILDINFO) which will be ignored
"""

import logging
import multiprocessing
import os

from chromite.lib import commandline
from chromite.lib import cros_build_lib
from chromite.lib import osutils
from chromite.lib import parallel
from chromite.scripts import cros_generate_breakpad_symbols


def GenerateBreakpadSymbols(breakpad_dir, symbols_dir):
    """Generate symbols for all binaries in symbols_dir.

    Args:
        breakpad_dir: The full path in which to write out breakpad symbols.
        symbols_dir: The full path to the binaries to process from.

    Returns:
        The number of errors that were encountered.
    """
    osutils.SafeMakedirs(breakpad_dir)
    logging.info("generating breakpad symbols from %s", symbols_dir)

    num_errors = parallel.WrapMultiprocessing(multiprocessing.Value, "i")

    # Now start generating symbols for the discovered elfs.
    with parallel.BackgroundTaskRunner(
        cros_generate_breakpad_symbols.GenerateBreakpadSymbol,
        breakpad_dir=breakpad_dir,
        num_errors=num_errors,
        # Mesa driver libraries fail with "-d".
        dump_syms_args=["-v", "-m"],
    ) as queue:
        for root, _, files in os.walk(symbols_dir):
            for f in files:
                queue.put([os.path.join(root, f)])

    return num_errors.value


def ProcessSymbolsTarball(archive, breakpad_dir, symbols_path) -> None:
    """Extract, process, and upload all symbols in a symbols file.

    Take the symbols file build artifact from an Borealis build, process it
    into breakpad format.

    The symbols files are really expected to be unstripped elf .debug files
    (or libraries).

    Args:
        archive: Name of the tarball to process.
        breakpad_dir: Root directory for writing out breakpad files.
        symbols_path: Relative directory to search for binaries.
    """
    with osutils.TempDir(prefix="extracted-") as extract_dir:
        logging.info("Extracting %s into %s", archive, extract_dir)
        # We are trusting the contents from a security point of view.
        cros_build_lib.ExtractTarball(archive, extract_dir)

        logging.info(
            "Generate breakpad symbols from %s into %s",
            extract_dir,
            breakpad_dir,
        )
        GenerateBreakpadSymbols(
            breakpad_dir, os.path.join(extract_dir, symbols_path)
        )


def get_parser():
    """Returns a command line parser."""
    parser = commandline.ArgumentParser(description=__doc__)

    parser.add_argument(
        "--symbols-file",
        type="str_path",
        required=True,
        help="Tarball containing debug binaries",
    )
    parser.add_argument(
        "--symbols-path",
        default="usr/lib/debug",
        help="Path to search for debug binaries",
    )
    parser.add_argument(
        "--breakpad-dir",
        type="str_path",
        required=True,
        help="Root directory for breakpad symbol files.",
    )
    return parser


def main(argv) -> None:
    """Helper method mostly used for manual testing."""
    parser = get_parser()
    opts = parser.parse_args(argv)
    opts.Freeze()

    ProcessSymbolsTarball(
        opts.symbols_file, opts.breakpad_dir, opts.symbols_path
    )
