/* Self tests for GDB command definitions for GDB, the GNU debugger.

   Copyright (C) 2019-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 "cli/cli-cmds.h"
#include "cli/cli-decode.h"
#include "gdbsupport/selftest.h"
#include "gdbsupport/unordered_map.h"

namespace selftests {

/* Verify some invariants of GDB commands documentation.  */

namespace help_doc_tests {

static unsigned int nr_failed_invariants;

/* Report a broken invariant and increments nr_failed_invariants.  */

static void
broken_doc_invariant (const char *prefix, const char *name, const char *msg)
{
  gdb_printf ("help doc broken invariant: command '%s%s' help doc %s\n",
	      prefix, name, msg);
  nr_failed_invariants++;
}

/* Recursively walk the commandlist structures, and check doc invariants:
   - The first line of the doc must end with a '.'.
   - the doc must not end with a new line.
  If an invariant is not respected, produce a message and increment
  nr_failed_invariants.
  Note that we do not call SELF_CHECK in this function, as we want
  all commands to be checked before making the test fail.  */

static void
check_doc (struct cmd_list_element *commandlist, const char *prefix)
{
  struct cmd_list_element *c;

  /* Walk through the commands.  */
  for (c = commandlist; c; c = c->next)
    {
      /* Checks the doc has a first line terminated with a '.'.  */
      const char *p = c->doc;

      /* Position p on the first LF, or on terminating null byte.  */
      while (*p && *p != '\n')
	p++;
      if (p == c->doc)
	broken_doc_invariant
	  (prefix, c->name,
	   "is missing the first line terminated with a '.' character");
      else if (*(p-1) != '.')
	broken_doc_invariant
	  (prefix, c->name,
	   "first line is not terminated with a '.' character");

      /* Checks the doc is not terminated with a new line.  */
      if (c_isspace (c->doc[strlen (c->doc) - 1]))
	broken_doc_invariant
	  (prefix, c->name,
	   "has superfluous trailing whitespace");

      const char *prev_start = c->doc;
      for (const char *nl = strchr (c->doc, '\n');
	   nl != nullptr;
	   nl = strchr (prev_start, '\n'))
	{
	  if (nl == c->doc)
	    broken_doc_invariant (prefix, c->name, "has a leading newline");
	  else
	    {
	      /* \n\n is ok, so we check that explicitly here.  */
	      if (c_isspace (nl[-1]) && nl[-1] != '\n')
		broken_doc_invariant (prefix, c->name,
				      "has whitespace before a newline");
	    }

	  if (nl - prev_start > cli_help_line_length)
	    broken_doc_invariant (prefix, c->name, "has over-long line");
	  prev_start = nl + 1;
	}

      if (strlen (prev_start) > cli_help_line_length)
	broken_doc_invariant (prefix, c->name, "has over-long line");

      /* Check if this command has subcommands and is not an
	 abbreviation.  We skip checking subcommands of abbreviations
	 in order to avoid duplicates in the output.  */
      if (c->is_prefix () && !c->abbrev_flag)
	{
	  /* Recursively call ourselves on the subcommand list,
	     passing the right prefix in.  */
	  check_doc (*c->subcommands, c->prefixname ().c_str ());
	}
    }
}

static void
help_doc_invariants_tests ()
{
  nr_failed_invariants = 0;
  check_doc (cmdlist, "");
  SELF_CHECK (nr_failed_invariants == 0);
}

} /* namespace help_doc_tests */

/* Verify some invariants of GDB command structure.  */

namespace command_structure_tests {

/* Nr of commands in which a duplicated list is found.  */
static unsigned int nr_duplicates = 0;
/* Nr of commands in a list having no valid prefix cmd.  */
static unsigned int nr_invalid_prefixcmd = 0;

/* A map associating a list with the prefix leading to it.  */

static gdb::unordered_map<cmd_list_element **, const char *> lists;

/* Store each command list in lists, associated with the prefix to reach it.  A
   list must only be found once.

   Verifies that all elements of the list have the same non-null prefix
   command.  */

static void
traverse_command_structure (struct cmd_list_element **list,
			    const char *prefix)
{
  struct cmd_list_element *c, *prefixcmd;

  auto dupl = lists.find (list);
  if (dupl != lists.end ())
    {
      gdb_printf ("list %p duplicated,"
		  " reachable via prefix '%s' and '%s'."
		  "  Duplicated list first command is '%s'\n",
		  list,
		  prefix, dupl->second,
		  (*list)->name);
      nr_duplicates++;
      return;
    }

  lists.insert ({list, prefix});

  /* All commands of *list must have a prefix command equal to PREFIXCMD,
     the prefix command of the first command.  */
  if (*list == nullptr)
    prefixcmd = nullptr; /* A prefix command with an empty subcommand list.  */
  else
    prefixcmd = (*list)->prefix;

  /* Walk through the commands.  */
  for (c = *list; c; c = c->next)
    {
      /* If this command has subcommands and is not an alias,
	 traverse the subcommands.  */
      if (c->is_prefix () && !c->is_alias ())
	{
	  /* Recursively call ourselves on the subcommand list,
	     passing the right prefix in.  */
	  traverse_command_structure (c->subcommands, c->prefixname ().c_str ());
	}
      if (prefixcmd != c->prefix
	  || (prefixcmd == nullptr && *list != cmdlist))
	{
	  if (c->prefix == nullptr)
	    gdb_printf ("list %p reachable via prefix '%s'."
			"  command '%s' has null prefixcmd\n",
			list,
			prefix, c->name);
	  else
	    gdb_printf ("list %p reachable via prefix '%s'."
			"  command '%s' has a different prefixcmd\n",
			list,
			prefix, c->name);
	  nr_invalid_prefixcmd++;
	}
    }
}

/* Verify that a list of commands is present in the tree only once.  */

static void
command_structure_invariants_tests ()
{
  nr_duplicates = 0;
  nr_invalid_prefixcmd = 0;

  traverse_command_structure (&cmdlist, "");

  /* Release memory, be ready to be re-run.  */
  lists.clear ();

  SELF_CHECK (nr_duplicates == 0);
  SELF_CHECK (nr_invalid_prefixcmd == 0);
}

}

} /* namespace selftests */

INIT_GDB_FILE (command_def_selftests)
{
  selftests::register_test
    ("help_doc_invariants",
     selftests::help_doc_tests::help_doc_invariants_tests);

  selftests::register_test
    ("command_structure_invariants",
     selftests::command_structure_tests::command_structure_invariants_tests);
}
