/* Copyright (C) 2023 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"
#include "exceptions.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 (isspace (**curr))
	--(*curr);

      tok_end = *curr;

      while (!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 behaviour 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, error_str;

  if (error_msg != nullptr)
    error_str = std::string (error_msg) + "\n";

  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)
    {
      string_file buf;

      exception_print (&buf, ex);
      exception_msg = buf.release ();
    }

  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_str)
    {
      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 */

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