/* 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 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, 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
}
