# Test the SBAPI for GetStatistics()

import json
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]',
        )
        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)
