/* CLI options framework, for GDB.

   Copyright (C) 2017-2021 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 "cli/cli-option.h"
#include "cli/cli-decode.h"
#include "cli/cli-utils.h"
#include "cli/cli-setshow.h"
#include "command.h"
#include <vector>

namespace gdb {
namespace option {

/* An option's value.  Which field is active depends on the option's
   type.  */
union option_value
{
  /* For var_boolean options.  */
  bool boolean;

  /* For var_uinteger options.  */
  unsigned int uinteger;

  /* For var_zuinteger_unlimited options.  */
  int integer;

  /* For var_enum options.  */
  const char *enumeration;

  /* For var_string options.  This is malloc-allocated.  */
  char *string;
};

/* Holds an options definition and its value.  */
struct option_def_and_value
{
  /* The option definition.  */
  const option_def &option;

  /* A context.  */
  void *ctx;

  /* The option's value, if any.  */
  gdb::optional<option_value> value;

  /* Constructor.  */
  option_def_and_value (const option_def &option_, void *ctx_,
			gdb::optional<option_value> &&value_ = {})
    : option (option_),
      ctx (ctx_),
      value (std::move (value_))
  {
    clear_value (option_, value_);
  }

  /* Move constructor.  Need this because for some types the values
     are allocated on the heap.  */
  option_def_and_value (option_def_and_value &&rval)
    : option (rval.option),
      ctx (rval.ctx),
      value (std::move (rval.value))
  {
    clear_value (rval.option, rval.value);
  }

  DISABLE_COPY_AND_ASSIGN (option_def_and_value);

  ~option_def_and_value ()
  {
    if (value.has_value ())
      {
	if (option.type == var_string)
	  xfree (value->string);
      }
  }

private:

  /* Clear the option_value, without releasing it.  This is used after
     the value has been moved to some other option_def_and_value
     instance.  This is needed because for some types the value is
     allocated on the heap, so we must clear the pointer in the
     source, to avoid a double free.  */
  static void clear_value (const option_def &option,
			   gdb::optional<option_value> &value)
  {
    if (value.has_value ())
      {
	if (option.type == var_string)
	  value->string = nullptr;
      }
  }
};

static void save_option_value_in_ctx (gdb::optional<option_def_and_value> &ov);

/* Info passed around when handling completion.  */
struct parse_option_completion_info
{
  /* The completion word.  */
  const char *word;

  /* The tracker.  */
  completion_tracker &tracker;
};

/* If ARGS starts with "-", look for a "--" delimiter.  If one is
   found, then interpret everything up until the "--" as command line
   options.  Otherwise, interpret unknown input as the beginning of
   the command's operands.  */

static const char *
find_end_options_delimiter (const char *args)
{
  if (args[0] == '-')
    {
      const char *p = args;

      p = skip_spaces (p);
      while (*p)
	{
	  if (check_for_argument (&p, "--"))
	    return p;
	  else
	    p = skip_to_space (p);
	  p = skip_spaces (p);
	}
    }

  return nullptr;
}

/* Complete TEXT/WORD on all options in OPTIONS_GROUP.  */

static void
complete_on_options (gdb::array_view<const option_def_group> options_group,
		     completion_tracker &tracker,
		     const char *text, const char *word)
{
  size_t textlen = strlen (text);
  for (const auto &grp : options_group)
    for (const auto &opt : grp.options)
      if (strncmp (opt.name, text, textlen) == 0)
	{
	  tracker.add_completion
	    (make_completion_match_str (opt.name, text, word));
	}
}

/* See cli-option.h.  */

void
complete_on_all_options (completion_tracker &tracker,
			 gdb::array_view<const option_def_group> options_group)
{
  static const char opt[] = "-";
  complete_on_options (options_group, tracker, opt + 1, opt);
}

/* Parse ARGS, guided by OPTIONS_GROUP.  HAVE_DELIMITER is true if the
   whole ARGS line included the "--" options-terminator delimiter.  */

static gdb::optional<option_def_and_value>
parse_option (gdb::array_view<const option_def_group> options_group,
	      process_options_mode mode,
	      bool have_delimiter,
	      const char **args,
	      parse_option_completion_info *completion = nullptr)
{
  if (*args == nullptr)
    return {};
  else if (**args != '-')
    {
      if (have_delimiter)
	error (_("Unrecognized option at: %s"), *args);
      return {};
    }
  else if (check_for_argument (args, "--"))
    return {};

  /* Skip the initial '-'.  */
  const char *arg = *args + 1;

  const char *after = skip_to_space (arg);
  size_t len = after - arg;
  const option_def *match = nullptr;
  void *match_ctx = nullptr;

  for (const auto &grp : options_group)
    {
      for (const auto &o : grp.options)
	{
	  if (strncmp (o.name, arg, len) == 0)
	    {
	      if (match != nullptr)
		{
		  if (completion != nullptr && arg[len] == '\0')
		    {
		      complete_on_options (options_group,
					   completion->tracker,
					   arg, completion->word);
		      return {};
		    }

		  error (_("Ambiguous option at: -%s"), arg);
		}

	      match = &o;
	      match_ctx = grp.ctx;

	      if ((isspace (arg[len]) || arg[len] == '\0')
		  && strlen (o.name) == len)
		break; /* Exact match.  */
	    }
	}
    }

  if (match == nullptr)
    {
      if (have_delimiter || mode != PROCESS_OPTIONS_UNKNOWN_IS_OPERAND)
	error (_("Unrecognized option at: %s"), *args);

      return {};
    }

  if (completion != nullptr && arg[len] == '\0')
    {
      complete_on_options (options_group, completion->tracker,
			   arg, completion->word);
      return {};
    }

  *args += 1 + len;
  *args = skip_spaces (*args);
  if (completion != nullptr)
    completion->word = *args;

  switch (match->type)
    {
    case var_boolean:
      {
	if (!match->have_argument)
	  {
	    option_value val;
	    val.boolean = true;
	    return option_def_and_value {*match, match_ctx, val};
	  }

	const char *val_str = *args;
	int res;

	if (**args == '\0' && completion != nullptr)
	  {
	    /* Complete on both "on/off" and more options.  */

	    if (mode == PROCESS_OPTIONS_REQUIRE_DELIMITER)
	      {
		complete_on_enum (completion->tracker,
				  boolean_enums, val_str, val_str);
		complete_on_all_options (completion->tracker, options_group);
	      }
	    return option_def_and_value {*match, match_ctx};
	  }
	else if (**args == '-')
	  {
	    /* Treat:
		 "cmd -boolean-option -another-opt..."
	       as:
		 "cmd -boolean-option on -another-opt..."
	     */
	    res = 1;
	  }
	else if (**args == '\0')
	  {
	    /* Treat:
		 (1) "cmd -boolean-option "
	       as:
		 (1) "cmd -boolean-option on"
	     */
	    res = 1;
	  }
	else
	  {
	    res = parse_cli_boolean_value (args);
	    if (res < 0)
	      {
		const char *end = skip_to_space (*args);
		if (completion != nullptr)
		  {
		    if (*end == '\0')
		      {
			complete_on_enum (completion->tracker,
					  boolean_enums, val_str, val_str);
			return option_def_and_value {*match, match_ctx};
		      }
		  }

		if (have_delimiter)
		  error (_("Value given for `-%s' is not a boolean: %.*s"),
			 match->name, (int) (end - val_str), val_str);
		/* The user didn't separate options from operands
		   using "--", so treat this unrecognized value as the
		   start of the operands.  This makes "frame apply all
		   -past-main CMD" work.  */
		return option_def_and_value {*match, match_ctx};
	      }
	    else if (completion != nullptr && **args == '\0')
	      {
		/* While "cmd -boolean [TAB]" only offers "on" and
		   "off", the boolean option actually accepts "1",
		   "yes", etc. as boolean values.  We complete on all
		   of those instead of BOOLEAN_ENUMS here to make
		   these work:

		    "p -object 1[TAB]" -> "p -object 1 "
		    "p -object ye[TAB]" -> "p -object yes "

		   Etc.  Note that it's important that the space is
		   auto-appended.  Otherwise, if we only completed on
		   on/off here, then it might look to the user like
		   "1" isn't valid, like:
		   "p -object 1[TAB]" -> "p -object 1" (i.e., nothing happens).
		*/
		static const char *const all_boolean_enums[] = {
		  "on", "off",
		  "yes", "no",
		  "enable", "disable",
		  "0", "1",
		  nullptr,
		};
		complete_on_enum (completion->tracker, all_boolean_enums,
				  val_str, val_str);
		return {};
	      }
	  }

	option_value val;
	val.boolean = res;
	return option_def_and_value {*match, match_ctx, val};
      }
    case var_uinteger:
    case var_zuinteger_unlimited:
      {
	if (completion != nullptr)
	  {
	    if (**args == '\0')
	      {
		/* Convenience to let the user know what the option
		   can accept.  Note there's no common prefix between
		   the strings on purpose, so that readline doesn't do
		   a partial match.  */
		completion->tracker.add_completion
		  (make_unique_xstrdup ("NUMBER"));
		completion->tracker.add_completion
		  (make_unique_xstrdup ("unlimited"));
		return {};
	      }
	    else if (startswith ("unlimited", *args))
	      {
		completion->tracker.add_completion
		  (make_unique_xstrdup ("unlimited"));
		return {};
	      }
	  }

	if (match->type == var_zuinteger_unlimited)
	  {
	    option_value val;
	    val.integer = parse_cli_var_zuinteger_unlimited (args, false);
	    return option_def_and_value {*match, match_ctx, val};
	  }
	else
	  {
	    option_value val;
	    val.uinteger = parse_cli_var_uinteger (match->type, args, false);
	    return option_def_and_value {*match, match_ctx, val};
	  }
      }
    case var_enum:
      {
	if (completion != nullptr)
	  {
	    const char *after_arg = skip_to_space (*args);
	    if (*after_arg == '\0')
	      {
		complete_on_enum (completion->tracker,
				  match->enums, *args, *args);
		if (completion->tracker.have_completions ())
		  return {};

		/* If we don't have completions, let the
		   non-completion path throw on invalid enum value
		   below, so that completion processing stops.  */
	      }
	  }

	if (check_for_argument (args, "--"))
	  {
	    /* Treat e.g., "backtrace -entry-values --" as if there
	       was no argument after "-entry-values".  This makes
	       parse_cli_var_enum throw an error with a suggestion of
	       what are the valid options.  */
	    args = nullptr;
	  }

	option_value val;
	val.enumeration = parse_cli_var_enum (args, match->enums);
	return option_def_and_value {*match, match_ctx, val};
      }
    case var_string:
      {
	if (check_for_argument (args, "--"))
	  {
	    /* Treat e.g., "maint test-options -string --" as if there
	       was no argument after "-string".  */
	    error (_("-%s requires an argument"), match->name);
	  }

	const char *arg_start = *args;
	std::string str = extract_string_maybe_quoted (args);
	if (*args == arg_start)
	  error (_("-%s requires an argument"), match->name);

	option_value val;
	val.string = xstrdup (str.c_str ());
	return option_def_and_value {*match, match_ctx, val};
      }

    default:
      /* Not yet.  */
      gdb_assert_not_reached (_("option type not supported"));
    }

  return {};
}

/* See cli-option.h.  */

bool
complete_options (completion_tracker &tracker,
		  const char **args,
		  process_options_mode mode,
		  gdb::array_view<const option_def_group> options_group)
{
  const char *text = *args;

  tracker.set_use_custom_word_point (true);

  const char *delimiter = find_end_options_delimiter (text);
  bool have_delimiter = delimiter != nullptr;

  if (text[0] == '-' && (!have_delimiter || *delimiter == '\0'))
    {
      parse_option_completion_info completion_info {nullptr, tracker};

      while (1)
	{
	  *args = skip_spaces (*args);
	  completion_info.word = *args;

	  if (strcmp (*args, "-") == 0)
	    {
	      complete_on_options (options_group, tracker, *args + 1,
				   completion_info.word);
	    }
	  else if (strcmp (*args, "--") == 0)
	    {
	      tracker.add_completion (make_unique_xstrdup (*args));
	    }
	  else if (**args == '-')
	    {
	      gdb::optional<option_def_and_value> ov
		= parse_option (options_group, mode, have_delimiter,
				args, &completion_info);
	      if (!ov && !tracker.have_completions ())
		{
		  tracker.advance_custom_word_point_by (*args - text);
		  return mode == PROCESS_OPTIONS_REQUIRE_DELIMITER;
		}

	      if (ov
		  && ov->option.type == var_boolean
		  && !ov->value.has_value ())
		{
		  /* Looked like a boolean option, but we failed to
		     parse the value.  If this command requires a
		     delimiter, this value can't be the start of the
		     operands, so return true.  Otherwise, if the
		     command doesn't require a delimiter return false
		     so that the caller tries to complete on the
		     operand.  */
		  tracker.advance_custom_word_point_by (*args - text);
		  return mode == PROCESS_OPTIONS_REQUIRE_DELIMITER;
		}

	      /* If we parsed an option with an argument, and reached
		 the end of the input string with no trailing space,
		 return true, so that our callers don't try to
		 complete anything by themselves.  E.g., this makes it
		 so that with:

		  (gdb) frame apply all -limit 10[TAB]

		 we don't try to complete on command names.  */
	      if (ov
		  && !tracker.have_completions ()
		  && **args == '\0'
		  && *args > text && !isspace ((*args)[-1]))
		{
		  tracker.advance_custom_word_point_by
		    (*args - text);
		  return true;
		}

	      /* If the caller passed in a context, then it is
		 interested in the option argument values.  */
	      if (ov && ov->ctx != nullptr)
		save_option_value_in_ctx (ov);
	    }
	  else
	    {
	      tracker.advance_custom_word_point_by
		(completion_info.word - text);

	      /* If the command requires a delimiter, but we haven't
		 seen one, then return true, so that the caller
		 doesn't try to complete on whatever follows options,
		 which for these commands should only be done if
		 there's a delimiter.  */
	      if (mode == PROCESS_OPTIONS_REQUIRE_DELIMITER
		  && !have_delimiter)
		{
		  /* If we reached the end of the input string, then
		     offer all options, since that's all the user can
		     type (plus "--").  */
		  if (completion_info.word[0] == '\0')
		    complete_on_all_options (tracker, options_group);
		  return true;
		}
	      else
		return false;
	    }

	  if (tracker.have_completions ())
	    {
	      tracker.advance_custom_word_point_by
		(completion_info.word - text);
	      return true;
	    }
	}
    }
  else if (delimiter != nullptr)
    {
      tracker.advance_custom_word_point_by (delimiter - text);
      *args = delimiter;
      return false;
    }

  return false;
}

/* Save the parsed value in the option's context.  */

static void
save_option_value_in_ctx (gdb::optional<option_def_and_value> &ov)
{
  switch (ov->option.type)
    {
    case var_boolean:
      {
	bool value = ov->value.has_value () ? ov->value->boolean : true;
	*ov->option.var_address.boolean (ov->option, ov->ctx) = value;
      }
      break;
    case var_uinteger:
      *ov->option.var_address.uinteger (ov->option, ov->ctx)
	= ov->value->uinteger;
      break;
    case var_zuinteger_unlimited:
      *ov->option.var_address.integer (ov->option, ov->ctx)
	= ov->value->integer;
      break;
    case var_enum:
      *ov->option.var_address.enumeration (ov->option, ov->ctx)
	= ov->value->enumeration;
      break;
    case var_string:
      *ov->option.var_address.string (ov->option, ov->ctx)
	= ov->value->string;
      ov->value->string = nullptr;
      break;
    default:
      gdb_assert_not_reached ("unhandled option type");
    }
}

/* See cli-option.h.  */

bool
process_options (const char **args,
		 process_options_mode mode,
		 gdb::array_view<const option_def_group> options_group)
{
  if (*args == nullptr)
    return false;

  /* If ARGS starts with "-", look for a "--" sequence.  If one is
     found, then interpret everything up until the "--" as
     'gdb::option'-style command line options.  Otherwise, interpret
     ARGS as possibly the command's operands.  */
  bool have_delimiter = find_end_options_delimiter (*args) != nullptr;

  if (mode == PROCESS_OPTIONS_REQUIRE_DELIMITER && !have_delimiter)
    return false;

  bool processed_any = false;

  while (1)
    {
      *args = skip_spaces (*args);

      auto ov = parse_option (options_group, mode, have_delimiter, args);
      if (!ov)
	{
	  if (processed_any)
	    return true;
	  return false;
	}

      processed_any = true;

      save_option_value_in_ctx (ov);
    }
}

/* Helper for build_help.  Return a fragment of a help string showing
   OPT's possible values.  Returns NULL if OPT doesn't take an
   argument.  */

static const char *
get_val_type_str (const option_def &opt, std::string &buffer)
{
  if (!opt.have_argument)
    return nullptr;

  switch (opt.type)
    {
    case var_boolean:
      return "[on|off]";
    case var_uinteger:
    case var_zuinteger_unlimited:
      return "NUMBER|unlimited";
    case var_enum:
      {
	buffer = "";
	for (size_t i = 0; opt.enums[i] != nullptr; i++)
	  {
	    if (i != 0)
	      buffer += "|";
	    buffer += opt.enums[i];
	  }
	return buffer.c_str ();
      }
    case var_string:
      return "STRING";
    default:
      return nullptr;
    }
}

/* Helper for build_help.  Appends an indented version of DOC into
   HELP.  */

static void
append_indented_doc (const char *doc, std::string &help)
{
  const char *p = doc;
  const char *n = strchr (p, '\n');

  while (n != nullptr)
    {
      help += "    ";
      help.append (p, n - p + 1);
      p = n + 1;
      n = strchr (p, '\n');
    }
  help += "    ";
  help += p;
}

/* Fill HELP with an auto-generated "help" string fragment for
   OPTIONS.  */

static void
build_help_option (gdb::array_view<const option_def> options,
		   std::string &help)
{
  std::string buffer;

  for (const auto &o : options)
    {
      if (o.set_doc == nullptr)
	continue;

      help += "  -";
      help += o.name;

      const char *val_type_str = get_val_type_str (o, buffer);
      if (val_type_str != nullptr)
	{
	  help += ' ';
	  help += val_type_str;
	}
      help += "\n";
      append_indented_doc (o.set_doc, help);
      if (o.help_doc != nullptr)
	{
	  help += "\n";
	  append_indented_doc (o.help_doc, help);
	}
    }
}

/* See cli-option.h.  */

std::string
build_help (const char *help_tmpl,
	    gdb::array_view<const option_def_group> options_group)
{
  bool need_newlines = false;
  std::string help_str;

  const char *p = strstr (help_tmpl, "%OPTIONS%");
  help_str.assign (help_tmpl, p);

  for (const auto &grp : options_group)
    for (const auto &opt : grp.options)
      {
	if (need_newlines)
	  help_str += "\n\n";
	else
	  need_newlines = true;
	build_help_option (opt, help_str);
      }

  p += strlen ("%OPTIONS%");
  help_str.append (p);

  return help_str;
}

/* See cli-option.h.  */

void
add_setshow_cmds_for_options (command_class cmd_class,
			      void *data,
			      gdb::array_view<const option_def> options,
			      struct cmd_list_element **set_list,
			      struct cmd_list_element **show_list)
{
  for (const auto &option : options)
    {
      if (option.type == var_boolean)
	{
	  add_setshow_boolean_cmd (option.name, cmd_class,
				   option.var_address.boolean (option, data),
				   option.set_doc, option.show_doc,
				   option.help_doc,
				   nullptr, option.show_cmd_cb,
				   set_list, show_list);
	}
      else if (option.type == var_uinteger)
	{
	  add_setshow_uinteger_cmd (option.name, cmd_class,
				    option.var_address.uinteger (option, data),
				    option.set_doc, option.show_doc,
				    option.help_doc,
				    nullptr, option.show_cmd_cb,
				    set_list, show_list);
	}
      else if (option.type == var_zuinteger_unlimited)
	{
	  add_setshow_zuinteger_unlimited_cmd
	    (option.name, cmd_class,
	     option.var_address.integer (option, data),
	     option.set_doc, option.show_doc,
	     option.help_doc,
	     nullptr, option.show_cmd_cb,
	     set_list, show_list);
	}
      else if (option.type == var_enum)
	{
	  add_setshow_enum_cmd (option.name, cmd_class,
				option.enums,
				option.var_address.enumeration (option, data),
				option.set_doc, option.show_doc,
				option.help_doc,
				nullptr, option.show_cmd_cb,
				set_list, show_list);
	}
      else if (option.type == var_string)
	{
	  add_setshow_string_cmd (option.name, cmd_class,
				  option.var_address.string (option, data),
				  option.set_doc, option.show_doc,
				  option.help_doc,
				  nullptr, option.show_cmd_cb,
				  set_list, show_list);
	}
      else
	gdb_assert_not_reached (_("option type not handled"));
    }
}

} /* namespace option */
} /* namespace gdb */
