# Copyright (C) 2021-2023 Free Software Foundation, Inc.

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import xml.etree.ElementTree as ET
import gdb

# Make use of gdb.RemoteTargetConnection.send_packet to fetch the
# thread list from the remote target.
#
# Sending existing serial protocol packets like this is not a good
# idea, there should be better ways to get this information using an
# official API, this is just being used as a test case.
#
# Really, the send_packet API would be used to send target
# specific packets to the target, but these are, by definition, target
# specific, so hard to test in a general testsuite.
def get_thread_list_str():
    start_pos = 0
    thread_desc = ""
    conn = gdb.selected_inferior().connection
    if not isinstance(conn, gdb.RemoteTargetConnection):
        raise gdb.GdbError("connection is the wrong type")
    while True:
        str = conn.send_packet("qXfer:threads:read::%d,200" % start_pos).decode("ascii")
        start_pos += 200
        c = str[0]
        str = str[1:]
        thread_desc += str
        if c == "l":
            break
    return thread_desc


# Use gdb.RemoteTargetConnection.send_packet to manually fetch the
# thread list, then extract the thread list using the gdb.Inferior and
# gdb.InferiorThread API.  Compare the two results to ensure we
# managed to successfully read the thread list from the remote.
def run_send_packet_test():
    # Find the IDs of all current threads.
    all_threads = {}
    for inf in gdb.inferiors():
        for thr in inf.threads():
            id = "p%x.%x" % (thr.ptid[0], thr.ptid[1])
            all_threads[id] = False

    # Now fetch the thread list from the remote, and parse the XML.
    str = get_thread_list_str()
    threads_xml = ET.fromstring(str)

    # Look over all threads in the XML list and check we expected to
    # find them, mark the ones we do find.
    for thr in threads_xml:
        id = thr.get("id")
        if not id in all_threads:
            raise "found unexpected thread in remote thread list"
        else:
            all_threads[id] = True

    # Check that all the threads were found in the XML list.
    for id in all_threads:
        if not all_threads[id]:
            raise "thread missingt from remote thread list"

    # Test complete.
    print("Send packet test passed")


# Convert a bytes object to a string.  This follows the same rules as
# the 'maint packet' command so that the output from the two sources
# can be compared.
def bytes_to_string(byte_array):
    res = ""
    for b in byte_array:
        b = int(b)
        if b >= 32 and b <= 126:
            res = res + ("%c" % b)
        else:
            res = res + ("\\x%02x" % b)
    return res


# A very simple test for sending the packet that reads the auxv data.
# We convert the result to a string and expect to find some
# hex-encoded bytes in the output.  This test will only work on
# targets that actually supply auxv data.
def run_auxv_send_packet_test(expected_result):
    inf = gdb.selected_inferior()
    conn = inf.connection
    assert isinstance(conn, gdb.RemoteTargetConnection)
    res = conn.send_packet("qXfer:auxv:read::0,1000")
    assert isinstance(res, bytes)
    string = bytes_to_string(res)
    assert string.count("\\x") > 0
    assert string == expected_result
    print("auxv send packet test passed")


# Check that the value of 'global_var' is EXPECTED_VAL.
def check_global_var(expected_val):
    val = int(gdb.parse_and_eval("global_var"))
    val = val & 0xFFFFFFFF
    if val != expected_val:
        raise gdb.GdbError("global_var is 0x%x, expected 0x%x" % (val, expected_val))


# Return a bytes object representing an 'X' packet header with
# address ADDR.
def xpacket_header(addr):
    return ("X%x,4:" % addr).encode("ascii")


# Set the 'X' packet to the remote target to set a global variable.
# Checks that we can send byte values.
def run_set_global_var_test():
    inf = gdb.selected_inferior()
    conn = inf.connection
    assert isinstance(conn, gdb.RemoteTargetConnection)
    addr = gdb.parse_and_eval("&global_var")
    res = conn.send_packet("X%x,4:\x01\x01\x01\x01" % addr)
    assert isinstance(res, bytes)
    check_global_var(0x01010101)
    res = conn.send_packet(xpacket_header(addr) + b"\x02\x02\x02\x02")
    assert isinstance(res, bytes)
    check_global_var(0x02020202)

    # This first attempt will not work as we're passing a Unicode string
    # containing non-ascii characters.
    saw_error = False
    try:
        res = conn.send_packet("X%x,4:\xff\xff\xff\xff" % addr)
    except UnicodeError:
        saw_error = True
    except:
        assert False

    assert saw_error
    check_global_var(0x02020202)
    # Now we pass a bytes object, which will work.
    res = conn.send_packet(xpacket_header(addr) + b"\xff\xff\xff\xff")
    check_global_var(0xFFFFFFFF)

    print("set global_var test passed")


# Just to indicate the file was sourced correctly.
print("Sourcing complete.")
