# 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.

"""cros debug: Debug the applications on the target device."""

import logging
import os

from chromite.cli import command
from chromite.lib import commandline
from chromite.lib import cros_build_lib
from chromite.lib import remote_access


@command.command_decorator("debug")
class DebugCommand(command.CliCommand):
    """Use GDB to debug a process running on the target device.

    This command starts a GDB session to debug a remote process running on the
    target device. The remote process can either be an existing process or newly
    started by calling this command.

    This command can also be used to find out information about all running
    processes of an executable on the target device.
    """

    EPILOG = """
To list all running processes of an executable:
    cros debug device --list --exe=/path/to/executable

To debug an executable:
    cros debug device --exe=/path/to/executable

To debug a process by its pid:
    cros debug device --pid=1234
"""

    def __init__(self, options):
        """Initialize DebugCommand."""
        super().__init__(options)
        # SSH connection settings.
        self.ssh_hostname = None
        self.ssh_port = None
        self.ssh_username = None
        self.ssh_private_key = None
        # The board name of the target device.
        self.board = None
        # Settings of the process to debug.
        self.list = False
        self.exe = None
        self.pid = None
        # The command for starting gdb.
        self.gdb_cmd = None

    @classmethod
    def AddParser(cls, parser):
        """Add parser arguments."""
        super(cls, DebugCommand).AddParser(parser)
        cls.AddDeviceArgument(parser, positional=True)
        parser.add_argument(
            "--board",
            default=None,
            help="The board to use. By default it is "
            "automatically detected. You can override the detected board with "
            "this option.",
        )
        parser.add_argument(
            "--private-key",
            type="path",
            default=None,
            help="SSH identity file (private key).",
        )
        parser.add_argument(
            "-l",
            "--list",
            action="store_true",
            default=False,
            help="List running processes of the executable on the target "
            "device.",
        )
        parser.add_argument(
            "--exe", help="Full path of the executable on the target device."
        )
        parser.add_argument(
            "-p",
            "--pid",
            type=int,
            help="The pid of the process on the target device.",
        )

    @classmethod
    def ProcessOptions(cls, parser, options):
        """Post process options."""
        if not (options.pid or options.exe):
            parser.error(
                "Must use --exe or --pid to specify the process to debug."
            )

        if options.pid and (options.list or options.exe):
            parser.error("--list and --exe are disallowed when --pid is used.")

        if not options.exe.startswith("/"):
            parser.error("--exe must have a full pathname.")

    def _ListProcesses(self, device, pids):
        """Print out information of the processes in |pids|."""
        if not pids:
            logging.info(
                "No running process of %s on device %s",
                self.exe,
                self.ssh_hostname,
            )
            return

        try:
            result = device.run(["ps", "aux"])
            lines = result.stdout.splitlines()
            try:
                header, procs = lines[0], lines[1:]
                info = os.linesep.join(
                    [p for p in procs if int(p.split()[1]) in pids]
                )
            except ValueError:
                cros_build_lib.Die("Parsing output failed:\n%s", result.stdout)

            print(
                "\nList running processes of %s on device %s:\n%s\n%s"
                % (self.exe, self.ssh_hostname, header, info)
            )
        except cros_build_lib.RunCommandError:
            cros_build_lib.Die(
                "Failed to find any running process on device %s",
                self.ssh_hostname,
            )

    def _DebugNewProcess(self):
        """Start a new process on the target device and attach gdb to it."""
        logging.info(
            "Ready to start and debug %s on device %s",
            self.exe,
            self.ssh_hostname,
        )
        cros_build_lib.run(self.gdb_cmd + ["--remote_file", self.exe])

    def _DebugRunningProcess(self, pid):
        """Start gdb and attach it to the remote running process with |pid|."""
        logging.info(
            "Ready to debug process %d on device %s", pid, self.ssh_hostname
        )
        cros_build_lib.run(self.gdb_cmd + ["--pid", str(pid)])

    def _ReadOptions(self):
        """Process options and set variables."""
        if self.options.device:
            self.ssh_hostname = self.options.device.hostname
            self.ssh_username = self.options.device.username
            self.ssh_port = self.options.device.port
        self.ssh_private_key = self.options.private_key
        self.list = self.options.list
        self.exe = self.options.exe
        self.pid = self.options.pid

    def Run(self):
        """Run cros debug."""
        commandline.RunInsideChroot(self)
        self._ReadOptions()
        with remote_access.ChromiumOSDeviceHandler(
            self.ssh_hostname,
            port=self.ssh_port,
            username=self.ssh_username,
            private_key=self.ssh_private_key,
        ) as device:
            self.board = cros_build_lib.GetBoard(
                device_board=device.board,
                override_board=self.options.board,
                strict=True,
            )
            logging.info("Board is %s", self.board)

            self.gdb_cmd = [
                "gdb_remote",
                "--ssh",
                "--board",
                self.board,
                "--remote",
                self.ssh_hostname,
            ]
            if self.ssh_port:
                self.gdb_cmd.extend(["--ssh_port", str(self.ssh_port)])

            if self.pid:
                self._DebugRunningProcess(self.pid)
                return

            logging.debug("Executable path is %s", self.exe)
            if not device.IsFileExecutable(self.exe):
                cros_build_lib.Die(
                    'File path "%s" does not exist or is not executable on '
                    "device %s",
                    self.exe,
                    self.ssh_hostname,
                )

            pids = device.GetRunningPids(self.exe)
            self._ListProcesses(device, pids)

            if self.list:
                # If '--list' flag is on, do not launch GDB.
                return

            if pids:
                choices = ["Start a new process under GDB"]
                choices.extend(pids)
                idx = cros_build_lib.GetChoice(
                    "Please select the process pid to debug (select [0] to "
                    "start a new process):",
                    choices,
                )
                if idx == 0:
                    self._DebugNewProcess()
                else:
                    self._DebugRunningProcess(pids[idx - 1])
            else:
                self._DebugNewProcess()
