"""
Test that plugins that load commands work correctly.
"""

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


class PluginCommandTestCase(TestBase):
    SHARED_BUILD_TESTCASE = False

    def setUp(self):
        TestBase.setUp(self)

    @skipIfNoSBHeaders
    @skipIfHostIncompatibleWithTarget
    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")
    @no_debug_info_test
    def test_load_plugin(self):
        """Test that plugins that load commands work correctly."""
        self.generateSource("plugin.cpp")

        plugin_name = "plugin"
        if sys.platform.startswith("darwin"):
            plugin_lib_name = "lib%s.dylib" % plugin_name
        else:
            plugin_lib_name = "lib%s.so" % plugin_name

        # Invoke the library build rule.
        self.buildLibrary("plugin.cpp", plugin_name)

        retobj = lldb.SBCommandReturnObject()

        cinterpreter = self.dbg.GetCommandInterpreter()
        retval = cinterpreter.HandleCommand(
            "plugin load %s" % self.getBuildArtifact(plugin_lib_name), retobj
        )

        self.assertTrue(cinterpreter.UserCommandExists("plugin_loaded_command"))
        retobj.Clear()

        retval = self.dbg.GetCommandInterpreter().HandleCommand(
            "plugin_loaded_command child abc def ghi", retobj
        )

        if self.TraceOn():
            print(retobj.GetOutput())

        self.expect(retobj, substrs=["abc def ghi"], exe=False)

        retobj.Clear()

        # check that abbreviations work correctly in plugin commands.
        retval = self.dbg.GetCommandInterpreter().HandleCommand(
            "plugin_loaded_ ch abc def ghi", retobj
        )

        if self.TraceOn():
            print(retobj.GetOutput())

        self.expect(retobj, substrs=["abc def ghi"], exe=False)

    @no_debug_info_test
    def test_invalid_plugin_invocation(self):
        self.expect(
            "plugin load a b",
            error=True,
            startstr="error: 'plugin load' requires one argument",
        )
        self.expect(
            "plugin load",
            error=True,
            startstr="error: 'plugin load' requires one argument",
        )

    @no_debug_info_test
    def test_invalid_plugin_target(self):
        self.expect(
            "plugin load ThisIsNotAValidPluginName",
            error=True,
            startstr="error: no such file",
        )
