/* Copyright (C) 2023-2025 Free Software Foundation, Inc.

   This file is part of GDB.

   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/>.  */

#include "defs.h"
#include "gdbsupport/gdb_assert.h"
#include "gdbsupport/selftest.h"
#include "test-target.h"
#include "scoped-mock-context.h"
#include "break-cond-parse.h"
#include "tid-parse.h"
#include "ada-lang.h"

/* When parsing tokens from a string, which direction are we parsing?

   Given the following string and pointer 'ptr':

	ABC DEF GHI JKL
	       ^
	       ptr

   Parsing 'forward' will return the token 'GHI' and update 'ptr' to point
   between GHI and JKL.  Parsing 'backward' will return the token 'DEF' and
   update 'ptr' to point between ABC and DEF.
*/

enum class parse_direction
{
  /* Parse the next token forwards.  */
  forward,

  /* Parse the previous token backwards.  */
  backward
};

/* Find the next token in DIRECTION from *CURR.  */

static std::string_view
find_next_token (const char **curr, parse_direction direction)
{
  const char *tok_start, *tok_end;

  gdb_assert (**curr != '\0');

  if (direction == parse_direction::forward)
    {
      *curr = skip_spaces (*curr);
      tok_start = *curr;
      *curr = skip_to_space (*curr);
      tok_end = *curr - 1;
    }
  else
    {
      gdb_assert (direction == parse_direction::backward);

      while (c_isspace (**curr))
	--(*curr);

      tok_end = *curr;

      while (!c_isspace (**curr))
	--(*curr);

      tok_start = (*curr) + 1;
    }

  return std::string_view (tok_start, tok_end - tok_start + 1);
}

/* A class that represents a complete parsed token.  Each token has a type
   and a std::string_view into the original breakpoint condition string.  */

struct token
{
  /* The types a token might take.  */
  enum class type
  {
    /* These are the token types for the 'if', 'thread', 'inferior', and
       'task' keywords.  The m_content for these token types is the value
       passed to the keyword, not the keyword itself.  */
    CONDITION,
    THREAD,
    INFERIOR,
    TASK,

    /* This is the token used when we find unknown content, the m_content
       for this token is the rest of the input string.  */
    REST,

    /* This is the token for the -force-condition token, the m_content for
       this token contains the keyword itself.  */
    FORCE
  };

  token (enum type type, std::string_view content)
    : m_type (type),
      m_content (std::move (content))
  {
    /* Nothing.  */
  }

  /* Return a string representing this token.  Only used for debug.  */
  std::string to_string () const
  {
    switch (m_type)
      {
      case type::CONDITION:
	return string_printf ("{ CONDITION: \"%s\" }",
			      std::string (m_content).c_str ());
      case type::THREAD:
	return string_printf ("{ THREAD: \"%s\" }",
			      std::string (m_content).c_str ());
      case type::INFERIOR:
	return string_printf ("{ INFERIOR: \"%s\" }",
			      std::string (m_content).c_str ());
      case type::TASK:
	return string_printf ("{ TASK: \"%s\" }",
			      std::string (m_content).c_str ());
      case type::REST:
	return string_printf ("{ REST: \"%s\" }",
			      std::string (m_content).c_str ());
      case type::FORCE:
	return string_printf ("{ FORCE }");
      default:
	return "** unknown **";
      }
  }

  /* The type of this token.  */
  const type &get_type () const
  {
    return m_type;
  }

  /* Return the value of this token.  */
  const std::string_view &get_value () const
  {
    gdb_assert (m_content.size () > 0);
    return m_content;
  }

  /* Extend this token with the contents of OTHER.  This only makes sense
     if OTHER is the next token after this one in the original string,
     however, enforcing that restriction is left to the caller of this
     function.

     When OTHER is a keyword/value token, e.g. 'thread 1', the m_content
     for OTHER will only point to the '1'.  However, as the m_content is a
     std::string_view, then when we merge the m_content of OTHER into this
     token we automatically merge in the 'thread' part too, as it
     naturally sits between this token and OTHER.  */

  void
  extend (const token &other)
  {
    m_content = std::string_view (this->m_content.data (),
				  (other.m_content.data ()
				   - this->m_content.data ()
				   + other.m_content.size ()));
  }

private:
  /* The type of this token.  */
  type m_type;

  /* The important content part of this token.  The extend member function
     depends on this being a std::string_view.  */
  std::string_view m_content;
};

/* Split STR, a breakpoint condition string, into a vector of tokens where
   each token represents a component of the condition.  Tokens are first
   parsed from the front of STR until we encounter an 'if' token.  At this
   point tokens are parsed from the end of STR until we encounter an
   unknown token, which we assume is the other end of the 'if' condition.
   If when scanning forward we encounter an unknown token then the
   remainder of STR is placed into a 'rest' token (the rest of the
   string), and no backward scan is performed.  */

static std::vector<token>
parse_all_tokens (const char *str)
{
  gdb_assert (str != nullptr);

  std::vector<token> forward_results;
  std::vector<token> backward_results;

  const char *cond_start = nullptr;
  const char *cond_end = nullptr;
  parse_direction direction = parse_direction::forward;
  std::vector<token> *curr_results = &forward_results;
  while (*str != '\0')
    {
      /* Find the next token.  If moving backward and this token starts at
	 the same location as the condition then we must have found the
	 other end of the condition string -- we're done.  */
      std::string_view t = find_next_token (&str, direction);
      if (direction == parse_direction::backward && t.data () <= cond_start)
	{
	  cond_end = &t.back ();
	  break;
	}

      /* We only have a single flag option to check for.  All the other
	 options take a value so require an additional token to be found.
	 Additionally, we require that this flag be at least '-f', we
	 don't allow it to be abbreviated to '-'.  */
      if (t.length () > 1 && startswith ("-force-condition", t))
	{
	  curr_results->emplace_back (token::type::FORCE, t);
	  continue;
	}

      /* Maybe the first token was the last token in the string.  If this
	 is the case then we definitely can't try to extract a value
	 token.  This also means that the token T is meaningless.  Reset
	 TOK to point at the start of the unknown content and break out of
	 the loop.  We'll record the unknown part of the string outside of
	 the scanning loop (below).  */
      if (direction == parse_direction::forward && *str == '\0')
	{
	  str = t.data ();
	  break;
	}

      /* As before, find the next token and, if we are scanning backwards,
	 check that we have not reached the start of the condition string.  */
      std::string_view v = find_next_token (&str, direction);
      if (direction == parse_direction::backward && v.data () <= cond_start)
	{
	  /* Use token T here as that must also be part of the condition
	     string.  */
	  cond_end = &t.back ();
	  break;
	}

      /* When moving backward we will first parse the value token then the
	 keyword token, so swap them now.  */
      if (direction == parse_direction::backward)
	std::swap (t, v);

      /* Check for valid option in token T.  If we find a valid option then
	 parse the value from the token V.  Except for 'if', that's handled
	 differently.

	 For the 'if' token we need to capture the entire condition
	 string, so record the start of the condition string and then
	 start scanning backwards looking for the end of the condition
	 string.

	 The order of these checks is important, at least the check for
	 'thread' must occur before the check for 'task'.  We accept
	 abbreviations of these token names, and 't' should resolve to
	 'thread', which will only happen if we check 'thread' first.  */
      if (direction == parse_direction::forward && startswith ("if", t))
	{
	  cond_start = v.data ();
	  str = str + strlen (str);
	  gdb_assert (*str == '\0');
	  --str;
	  direction = parse_direction::backward;
	  curr_results = &backward_results;
	  continue;
	}
      else if (startswith ("thread", t))
	curr_results->emplace_back (token::type::THREAD, v);
      else if (startswith ("inferior", t))
	curr_results->emplace_back (token::type::INFERIOR, v);
      else if (startswith ("task", t))
	curr_results->emplace_back (token::type::TASK, v);
      else
	{
	  /* An unknown token.  If we are scanning forward then reset TOK
	     to point at the start of the unknown content, we record this
	     outside of the scanning loop (below).

	     If we are scanning backward then unknown content is assumed to
	     be the other end of the condition string, obviously, this is
	     just a heuristic, we could be looking at a mistyped command
	     line, but this will be spotted when the condition is
	     eventually evaluated.

	     Either way, no more scanning is required after this.  */
	  if (direction == parse_direction::forward)
	    str = t.data ();
	  else
	    {
	      gdb_assert (direction == parse_direction::backward);
	      cond_end = &v.back ();
	    }
	  break;
	}
    }

  if (cond_start != nullptr)
    {
      /* If we found the start of a condition string then we should have
	 switched to backward scan mode, and found the end of the condition
	 string.  Capture the whole condition string into COND_STRING
	 now.  */
      gdb_assert (direction == parse_direction::backward);
      gdb_assert (cond_end != nullptr);

      std::string_view v (cond_start, cond_end - cond_start + 1);

      forward_results.emplace_back (token::type::CONDITION, v);
    }
  else if (*str != '\0')
    {
      /* If we didn't have a condition start pointer then we should still
	 be in forward scanning mode.  If we didn't reach the end of the
	 input string (TOK is not at the null character) then the rest of
	 the input string is garbage that we didn't understand.

	 Record the unknown content into REST.  The caller of this function
	 will report this as an error later on.  We could report the error
	 here, but we prefer to allow the caller to run other checks, and
	 prioritise other errors before reporting this problem.  */
      gdb_assert (direction == parse_direction::forward);
      gdb_assert (cond_end == nullptr);

      std::string_view v (str, strlen (str));

      forward_results.emplace_back (token::type::REST, v);
    }

  /* If we have tokens in the BACKWARD_RESULTS vector then this means that
     we found an 'if' condition (which will be the last thing in the
     FORWARD_RESULTS vector), and then we started a backward scan.

     The last tokens from the input string (those after the 'if' condition)
     will be the first tokens added to the BACKWARD_RESULTS vector, so the
     last items in the BACKWARD_RESULTS vector are those next to the 'if'
     condition.

     Check the tokens in the BACKWARD_RESULTS vector from back to front.
     If the tokens look invalid then we assume that they are actually part
     of the 'if' condition, and merge the token with the 'if' condition.
     If it turns out that this was incorrect and that instead the user just
     messed up entering the token value, then this will show as an error
     when parsing the 'if' condition.

     Doing this allows us to handle things like:

       break function if ( variable == thread )

     Where 'thread' is a local variable within 'function'.  When parsing
     this we will initially see 'thread )' as a thread token with ')' as
     the value.  However, the following code will spot that ')' is not a
     valid thread-id, and so we merge 'thread )' into the 'if' condition
     string.

     This code also handles the special treatment for '-force-condition',
     which exists for backwards compatibility reasons.  Traditionally this
     flag, if it occurred immediately after the 'if' condition, would be
     treated as part of the 'if' condition.  When the breakpoint condition
     parsing code was rewritten, this behavior was retained.  */
  gdb_assert (backward_results.empty ()
	      || (forward_results.back ().get_type ()
		  == token::type::CONDITION));
  while (!backward_results.empty ())
    {
      token &t = backward_results.back ();

      if (t.get_type () == token::type::FORCE)
	forward_results.back ().extend (std::move (t));
      else if (t.get_type () == token::type::THREAD)
	{
	  const char *end;
	  std::string v (t.get_value ());
	  if (is_thread_id (v.c_str (), &end) && *end == '\0')
	    break;
	  forward_results.back ().extend (std::move (t));
	}
      else if (t.get_type () == token::type::INFERIOR
	       || t.get_type () == token::type::TASK)
	{
	  /* Place the token's value into a null-terminated string, parse
	     the string as a number and check that the entire string was
	     parsed.  If this is true then this looks like a valid inferior
	     or task number, otherwise, assume an invalid id, and merge
	     this token with the 'if' token.  */
	  char *end;
	  std::string v (t.get_value ());
	  (void) strtol (v.c_str (), &end, 0);
	  if (end > v.c_str () && *end == '\0')
	    break;
	  forward_results.back ().extend (std::move (t));
	}
      else
	gdb_assert_not_reached ("unexpected token type");

      /* If we found an actual valid token above then we will have broken
	 out of the loop.  We only get here if the token was merged with
	 the 'if' condition, in which case we can discard the last token
	 and then check the token before that.  */
      backward_results.pop_back ();
    }

  /* If after the above checks we still have some tokens in the
     BACKWARD_RESULTS vector, then these need to be appended to the
     FORWARD_RESULTS vector.  However, we first reverse the order so that
     FORWARD_RESULTS retains the tokens in the order they appeared in the
     input string.  */
  if (!backward_results.empty ())
    forward_results.insert (forward_results.end (),
			    backward_results.rbegin (),
			    backward_results.rend ());

  return forward_results;
}

/* Called when the global debug_breakpoint is true.  Prints VEC to the
   debug output stream.  */

static void
dump_condition_tokens (const std::vector<token> &vec)
{
  gdb_assert (debug_breakpoint);

  bool first = true;
  std::string str = "Tokens: ";
  for (const token &t : vec)
    {
      if (!first)
	str += " ";
      first = false;
      str += t.to_string ();
    }
  breakpoint_debug_printf ("%s", str.c_str ());
}

/* See break-cond-parse.h.  */

void
create_breakpoint_parse_arg_string
  (const char *str, gdb::unique_xmalloc_ptr<char> *cond_string_ptr,
   int *thread_ptr, int *inferior_ptr, int *task_ptr,
   gdb::unique_xmalloc_ptr<char> *rest_ptr, bool *force_ptr)
{
  /* Set up the defaults.  */
  cond_string_ptr->reset ();
  rest_ptr->reset ();
  *thread_ptr = -1;
  *inferior_ptr = -1;
  *task_ptr = -1;
  *force_ptr = false;

  if (str == nullptr)
    return;

  /* Split STR into a series of tokens.  */
  std::vector<token> tokens = parse_all_tokens (str);
  if (debug_breakpoint)
    dump_condition_tokens (tokens);

  /* Temporary variables.  Initialised to the default state, then updated
     as we parse TOKENS.  If all of TOKENS is parsed successfully then the
     state from these variables is copied into the output arguments before
     the function returns.  */
  int thread = -1, inferior = -1, task = -1;
  bool force = false;
  gdb::unique_xmalloc_ptr<char> cond_string, rest;

  for (const token &t : tokens)
    {
      std::string tok_value (t.get_value ());
      switch (t.get_type ())
	{
	case token::type::FORCE:
	  force = true;
	  break;
	case token::type::THREAD:
	  {
	    if (thread != -1)
	      error ("You can specify only one thread.");
	    if (task != -1 || inferior != -1)
	      error ("You can specify only one of thread, inferior, or task.");
	    const char *tmptok;
	    thread_info *thr = parse_thread_id (tok_value.c_str (), &tmptok);
	    gdb_assert (*tmptok == '\0');
	    thread = thr->global_num;
	  }
	  break;
	case token::type::INFERIOR:
	  {
	    if (inferior != -1)
	      error ("You can specify only one inferior.");
	    if (task != -1 || thread != -1)
	      error ("You can specify only one of thread, inferior, or task.");
	    char *tmptok;
	    long inferior_id = strtol (tok_value.c_str (), &tmptok, 0);
	    if (*tmptok != '\0')
	      error (_("Junk '%s' after inferior keyword."), tmptok);
	    if (inferior_id > INT_MAX)
	      error (_("No inferior number '%ld'"), inferior_id);
	    inferior = static_cast<int> (inferior_id);
	    struct inferior *inf = find_inferior_id (inferior);
	    if (inf == nullptr)
	      error (_("No inferior number '%d'"), inferior);
	  }
	  break;
	case token::type::TASK:
	  {
	    if (task != -1)
	      error ("You can specify only one task.");
	    if (inferior != -1 || thread != -1)
	      error ("You can specify only one of thread, inferior, or task.");
	    char *tmptok;
	    long task_id = strtol (tok_value.c_str (), &tmptok, 0);
	    if (*tmptok != '\0')
	      error (_("Junk '%s' after task keyword."), tmptok);
	    if (task_id > INT_MAX)
	      error (_("Unknown task %ld"), task_id);
	    task = static_cast<int> (task_id);
	    if (!valid_task_id (task))
	      error (_("Unknown task %d."), task);
	  }
	  break;
	case token::type::CONDITION:
	  cond_string.reset (savestring (t.get_value ().data (),
					 t.get_value ().size ()));
	  break;
	case token::type::REST:
	  rest.reset (savestring (t.get_value ().data (),
				  t.get_value ().size ()));
	  break;
	}
    }

  /* Move results into the output locations.  */
  *force_ptr = force;
  *thread_ptr = thread;
  *inferior_ptr = inferior;
  *task_ptr = task;
  rest_ptr->reset (rest.release ());
  cond_string_ptr->reset (cond_string.release ());
}

#if GDB_SELF_TEST

namespace selftests {

/* Run a single test of the create_breakpoint_parse_arg_string function.
   INPUT is passed to create_breakpoint_parse_arg_string while all other
   arguments are the expected output from
   create_breakpoint_parse_arg_string.  */

static void
test (const char *input, const char *condition, int thread = -1,
      int inferior = -1, int task = -1, bool force = false,
      const char *rest = nullptr, const char *error_msg = nullptr)
{
  gdb::unique_xmalloc_ptr<char> extracted_condition;
  gdb::unique_xmalloc_ptr<char> extracted_rest;
  int extracted_thread, extracted_inferior, extracted_task;
  bool extracted_force_condition;
  std::string exception_msg;

  if (error_msg == nullptr)
    error_msg = "";

  try
    {
      create_breakpoint_parse_arg_string (input, &extracted_condition,
					  &extracted_thread,
					  &extracted_inferior,
					  &extracted_task, &extracted_rest,
					  &extracted_force_condition);
    }
  catch (const gdb_exception_error &ex)
    {
      exception_msg = ex.what ();
    }

  if ((condition == nullptr) != (extracted_condition.get () == nullptr)
      || (condition != nullptr
	  && strcmp (condition, extracted_condition.get ()) != 0)
      || (rest == nullptr) != (extracted_rest.get () == nullptr)
      || (rest != nullptr && strcmp (rest, extracted_rest.get ()) != 0)
      || thread != extracted_thread
      || inferior != extracted_inferior
      || task != extracted_task
      || force != extracted_force_condition
      || exception_msg != error_msg)
    {
      if (run_verbose ())
	{
	  debug_printf ("input: '%s'\n", input);
	  debug_printf ("condition: '%s'\n", extracted_condition.get ());
	  debug_printf ("rest: '%s'\n", extracted_rest.get ());
	  debug_printf ("thread: %d\n", extracted_thread);
	  debug_printf ("inferior: %d\n", extracted_inferior);
	  debug_printf ("task: %d\n", extracted_task);
	  debug_printf ("forced: %s\n",
			extracted_force_condition ? "true" : "false");
	  debug_printf ("exception: '%s'\n", exception_msg.c_str ());
	}

      /* Report the failure.  */
      SELF_CHECK (false);
    }
}

/* Wrapper for test function.  Pass through the default values for all
   parameters, except the last parameter, which indicates that we expect
   INPUT to trigger an error.  */

static void
test_error (const char *input, const char *error_msg)
{
  test (input, nullptr, -1, -1, -1, false, nullptr, error_msg);
}

/* Test the create_breakpoint_parse_arg_string function.  Just wraps
   multiple calls to the test function above.  */

static void
create_breakpoint_parse_arg_string_tests ()
{
  gdbarch *arch = current_inferior ()->arch ();
  scoped_restore_current_pspace_and_thread restore;
  scoped_mock_context<test_target_ops> mock_target (arch);

  int global_thread_num = mock_target.mock_thread.global_num;

  /* Test parsing valid breakpoint condition strings.  */
  test ("  if blah  ", "blah");
  test (" if blah thread 1", "blah", global_thread_num);
  test (" if blah inferior 1", "blah", -1, 1);
  test (" if blah thread 1  ", "blah", global_thread_num);
  test ("thread 1 woof", nullptr, global_thread_num, -1, -1, false, "woof");
  test ("thread 1 X", nullptr, global_thread_num, -1, -1, false, "X");
  test (" if blah thread 1 -force-condition", "blah", global_thread_num,
	-1, -1, true);
  test (" -force-condition if blah thread 1", "blah", global_thread_num,
	-1, -1, true);
  test (" -force-condition if blah thread 1  ", "blah", global_thread_num,
	-1, -1, true);
  test ("thread 1 -force-condition if blah", "blah", global_thread_num,
	-1, -1, true);
  test ("if (A::outer::func ())", "(A::outer::func ())");
  test ("if ( foo == thread )", "( foo == thread )");
  test ("if ( foo == thread ) inferior 1", "( foo == thread )", -1, 1);
  test ("if ( foo == thread ) thread 1", "( foo == thread )",
	global_thread_num);
  test ("if foo == thread", "foo == thread");
  test ("if foo == thread 1", "foo ==", global_thread_num);

  /* Test parsing some invalid breakpoint condition strings.  */
  test_error ("thread 1 if foo == 123 thread 1",
	      "You can specify only one thread.");
  test_error ("thread 1 if foo == 123 inferior 1",
	      "You can specify only one of thread, inferior, or task.");
  test_error ("thread 1 if foo == 123 task 1",
	      "You can specify only one of thread, inferior, or task.");
  test_error ("inferior 1 if foo == 123 inferior 1",
	      "You can specify only one inferior.");
  test_error ("inferior 1 if foo == 123 thread 1",
	      "You can specify only one of thread, inferior, or task.");
  test_error ("inferior 1 if foo == 123 task 1",
	      "You can specify only one of thread, inferior, or task.");
  test_error ("thread 1.2.3", "Invalid thread ID: 1.2.3");
  test_error ("thread 1/2", "Invalid thread ID: 1/2");
  test_error ("thread 1xxx", "Invalid thread ID: 1xxx");
  test_error ("inferior 1xxx", "Junk 'xxx' after inferior keyword.");
  test_error ("task 1xxx", "Junk 'xxx' after task keyword.");
}

} /* namespace selftests */
#endif /* GDB_SELF_TEST */

INIT_GDB_FILE (break_cond_parse)
{
#if GDB_SELF_TEST
  selftests::register_test
    ("create_breakpoint_parse_arg_string",
     selftests::create_breakpoint_parse_arg_string_tests);
#endif
}
