# Test the SBAPI for GetStatistics()

import json
import os

import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil


class TestStatsAPI(TestBase):
    NO_DEBUG_INFO_TESTCASE = True

    def test_stats_api(self):
        """
        Test SBTarget::GetStatistics() API.
        """
        self.build()
        exe = self.getBuildArtifact("a.out")
        # Launch a process and break
        (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
            self, "break here", lldb.SBFileSpec("main.c")
        )

        # Test enabling/disabling stats
        self.assertFalse(target.GetCollectingStats())
        target.SetCollectingStats(True)
        self.assertTrue(target.GetCollectingStats())
        target.SetCollectingStats(False)
        self.assertFalse(target.GetCollectingStats())

        # Test the function to get the statistics in JSON'ish.
        stats = target.GetStatistics()
        stream = lldb.SBStream()
        res = stats.GetAsJSON(stream)
        debug_stats = json.loads(stream.GetData())
        self.assertIn(
            "targets",
            debug_stats,
            'Make sure the "targets" key in in target.GetStatistics()',
        )
        self.assertIn(
            "modules",
            debug_stats,
            'Make sure the "modules" key in in target.GetStatistics()',
        )
        stats_json = debug_stats["targets"][0]
        self.assertIn(
            "expressionEvaluation",
            stats_json,
            'Make sure the "expressionEvaluation" key in in target.GetStatistics()["targets"][0]',
        )
        self.assertIn(
            "frameVariable",
            stats_json,
            'Make sure the "frameVariable" key in in target.GetStatistics()["targets"][0]',
        )
        self.assertNotIn(
            "loadCoreTime",
            stats_json,
            "LoadCoreTime should not be present in a live, non-coredump target",
        )
        expressionEvaluation = stats_json["expressionEvaluation"]
        self.assertIn(
            "successes",
            expressionEvaluation,
            'Make sure the "successes" key in in "expressionEvaluation" dictionary"',
        )
        self.assertIn(
            "failures",
            expressionEvaluation,
            'Make sure the "failures" key in in "expressionEvaluation" dictionary"',
        )
        frameVariable = stats_json["frameVariable"]
        self.assertIn(
            "successes",
            frameVariable,
            'Make sure the "successes" key in in "frameVariable" dictionary"',
        )
        self.assertIn(
            "failures",
            frameVariable,
            'Make sure the "failures" key in in "frameVariable" dictionary"',
        )

        # Test statistics summary.
        stats_options = lldb.SBStatisticsOptions()
        stats_options.SetSummaryOnly(True)
        stats_summary = target.GetStatistics(stats_options)
        stream_summary = lldb.SBStream()
        stats_summary.GetAsJSON(stream_summary)
        debug_stats_summary = json.loads(stream_summary.GetData())
        self.assertNotIn("modules", debug_stats_summary)
        self.assertNotIn("commands", debug_stats_summary)

        # Summary values should be the same as in full statistics.
        # The exceptions to this are:
        # - The parse time on Mac OS X is not deterministic.
        # - Memory usage may grow over time due to the use of ConstString.
        for key, value in debug_stats_summary.items():
            self.assertIn(key, debug_stats)
            if key != "memory" and key != "targets" and not key.endswith("Time"):
                self.assertEqual(debug_stats[key], value)

    def test_command_stats_api(self):
        """
        Test GetCommandInterpreter::GetStatistics() API.
        """
        self.build()
        exe = self.getBuildArtifact("a.out")
        lldbutil.run_to_name_breakpoint(self, "main")

        interp = self.dbg.GetCommandInterpreter()
        result = lldb.SBCommandReturnObject()
        interp.HandleCommand("bt", result)

        stream = lldb.SBStream()
        res = interp.GetStatistics().GetAsJSON(stream)
        command_stats = json.loads(stream.GetData())

        # Verify bt command is correctly parsed into final form.
        self.assertEqual(command_stats["thread backtrace"], 1)
        # Verify original raw command is not duplicatedly captured.
        self.assertNotIn("bt", command_stats)
        # Verify bt's regex command is not duplicatedly captured.
        self.assertNotIn("_regexp-bt", command_stats)

    @add_test_categories(["dwo"])
    def test_command_stats_force(self):
        """
        Test reporting all pssible debug info stats by force loading all debug
        info. For example, dwo files
        """
        src_dir = self.getSourceDir()
        dwo_yaml_path = os.path.join(src_dir, "main-main.dwo.yaml")
        exe_yaml_path = os.path.join(src_dir, "main.yaml")
        dwo_path = self.getBuildArtifact("main-main.dwo")
        exe_path = self.getBuildArtifact("main")
        self.yaml2obj(dwo_yaml_path, dwo_path)
        self.yaml2obj(exe_yaml_path, exe_path)

        # Turn on symbols on-demand loading
        self.runCmd("settings set symbols.load-on-demand true")

        # We need the current working directory to be set to the build directory
        os.chdir(self.getBuildDir())
        # Create a target with the object file we just created from YAML
        target = self.dbg.CreateTarget(exe_path)
        self.assertTrue(target, VALID_TARGET)

        # Get statistics
        stats_options = lldb.SBStatisticsOptions()
        stats = target.GetStatistics(stats_options)
        stream = lldb.SBStream()
        stats.GetAsJSON(stream)
        debug_stats = json.loads(stream.GetData())
        self.assertEqual(debug_stats["totalDebugInfoByteSize"], 193)

        # Get statistics with force loading
        stats_options.SetReportAllAvailableDebugInfo(True)
        stats_force = target.GetStatistics(stats_options)
        stream_force = lldb.SBStream()
        stats_force.GetAsJSON(stream_force)
        debug_stats_force = json.loads(stream_force.GetData())
        self.assertEqual(debug_stats_force["totalDebugInfoByteSize"], 445)

    def test_core_load_time(self):
        """
        Test to see if the coredump path is included in statistics dump.
        """
        yaml_file = "arm64-minidump-build-ids.yaml"
        src_dir = self.getSourceDir()
        minidump_path = self.getBuildArtifact(os.path.basename(yaml_file) + ".dmp")
        self.yaml2obj(os.path.join(src_dir, yaml_file), minidump_path)
        target = self.dbg.CreateTarget(None)
        process = target.LoadCore(minidump_path)
        self.assertTrue(process.IsValid())

        stats_options = lldb.SBStatisticsOptions()
        stats = target.GetStatistics(stats_options)
        stream = lldb.SBStream()
        stats.GetAsJSON(stream)
        debug_stats = json.loads(stream.GetData())
        self.assertTrue("targets" in debug_stats)
        target_info = debug_stats["targets"][0]
        self.assertTrue("loadCoreTime" in target_info)
        self.assertTrue(float(target_info["loadCoreTime"]) > 0.0)

    def test_command_stats_coredump(self):
        """
        Test to see if the coredump path is included in statistics dump.
        """
        yaml_file = "minidump.yaml"
        minidump_path = self.getBuildArtifact(os.path.basename(yaml_file) + ".dmp")
        self.yaml2obj(yaml_file, minidump_path)
        target = self.dbg.CreateTarget(None)
        process = target.LoadCore(minidump_path)
        self.assertTrue(process.IsValid())

        stats_options = lldb.SBStatisticsOptions()
        stats = target.GetStatistics(stats_options)
        stream = lldb.SBStream()
        stats.GetAsJSON(stream)
        debug_stats = json.loads(stream.GetData())
        self.assertTrue("targets" in debug_stats)
        target_info = debug_stats["targets"][0]
        self.assertTrue("coreFile" in target_info)
        self.assertEqual(target_info["coreFile"], os.path.basename(minidump_path))
