/* Find near-matches for strings and identifiers.
   Copyright (C) 2015-2022 Free Software Foundation, Inc.

This file is part of GCC.

GCC 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, or (at your option) any later
version.

GCC 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 GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#ifndef GCC_SPELLCHECK_H
#define GCC_SPELLCHECK_H

typedef unsigned int edit_distance_t;
const edit_distance_t MAX_EDIT_DISTANCE = UINT_MAX;

/* spellcheck.cc  */
extern edit_distance_t
get_edit_distance (const char *s, int len_s,
		   const char *t, int len_t);

extern edit_distance_t
get_edit_distance (const char *s, const char *t);

extern const char *
find_closest_string (const char *target,
		     const auto_vec<const char *> *candidates);

/* A traits class for describing a string-like type usable by
   class best_match.
   Specializations should provide the implementations of the following:

     static size_t get_length (TYPE);
     static const char *get_string (TYPE);

   get_string should return a non-NULL ptr, which does not need to be
   0-terminated.  */

template <typename TYPE>
struct edit_distance_traits {};

/* Specialization of edit_distance_traits for C-style strings.  */

template <>
struct edit_distance_traits<const char *>
{
  static size_t get_length (const char *str)
  {
    gcc_assert (str);
    return strlen (str);
  }

  static const char *get_string (const char *str)
  {
    gcc_assert (str);
    return str;
  }
};

extern edit_distance_t get_edit_distance_cutoff (size_t goal_len,
						 size_t candidate_len);

/* A type for use when determining the best match against a string,
   expressed as a template so that we can match against various
   string-like types (const char *, frontend identifiers, and preprocessor
   macros).

   This type accumulates the best possible match against GOAL_TYPE for
   a sequence of elements of CANDIDATE_TYPE, whilst minimizing the
   number of calls to get_edit_distance and to
   edit_distance_traits<T>::get_length.  */

template <typename GOAL_TYPE, typename CANDIDATE_TYPE>
class best_match
{
 public:
  typedef GOAL_TYPE goal_t;
  typedef CANDIDATE_TYPE candidate_t;
  typedef edit_distance_traits<goal_t> goal_traits;
  typedef edit_distance_traits<candidate_t> candidate_traits;

  /* Constructor.  */

  best_match (GOAL_TYPE goal,
	      edit_distance_t best_distance_so_far = MAX_EDIT_DISTANCE)
  : m_goal (goal_traits::get_string (goal)),
    m_goal_len (goal_traits::get_length (goal)),
    m_best_candidate (NULL),
    m_best_distance (best_distance_so_far)
  {}

  /* Compare the edit distance between CANDIDATE and m_goal,
     and if it's the best so far, record it.  */

  void consider (candidate_t candidate)
  {
    size_t candidate_len = candidate_traits::get_length (candidate);

    /* Calculate a lower bound on the candidate's distance to the goal,
       based on the difference in lengths; it will require at least
       this many insertions/deletions.  */
    edit_distance_t min_candidate_distance
      = abs ((ssize_t)candidate_len - (ssize_t)m_goal_len);

    /* If the candidate's length is sufficiently different to that
       of the goal string, then the number of insertions/deletions
       may be >= the best distance so far.  If so, we can reject
       the candidate immediately without needing to compute
       the exact distance, since it won't be an improvement.  */
    if (min_candidate_distance >= m_best_distance)
      return;

    /* If the candidate will be unable to beat the criterion in
       get_best_meaningful_candidate, reject it without computing
       the exact distance.  */
    edit_distance_t cutoff = get_cutoff (candidate_len);
    if (min_candidate_distance > cutoff)
      return;

    /* Otherwise, compute the distance and see if the candidate
       has beaten the previous best value.  */
    edit_distance_t dist
      = get_edit_distance (m_goal, m_goal_len,
			   candidate_traits::get_string (candidate),
			   candidate_len);
    if (dist < m_best_distance)
      {
	m_best_distance = dist;
	m_best_candidate = candidate;
	m_best_candidate_len = candidate_len;
      }
  }

  /* Assuming that BEST_CANDIDATE is known to be better than
     m_best_candidate, update (without recomputing the edit distance to
     the goal).  */

  void set_best_so_far (CANDIDATE_TYPE best_candidate,
			edit_distance_t best_distance,
			size_t best_candidate_len)
  {
    gcc_assert (best_distance < m_best_distance);
    m_best_candidate = best_candidate;
    m_best_distance = best_distance;
    m_best_candidate_len = best_candidate_len;
  }

  /* Generate the maximum edit distance for which we consider a suggestion
     to be meaningful, given a candidate of length CANDIDATE_LEN.  */

  edit_distance_t get_cutoff (size_t candidate_len) const
  {
    return ::get_edit_distance_cutoff (m_goal_len, candidate_len);
  }

  /* Get the best candidate so far, but applying a filter to ensure
     that we return NULL if none of the candidates are close to the goal,
     to avoid offering nonsensical suggestions to the user.  */

  candidate_t get_best_meaningful_candidate () const
  {
    /* If the edit distance is too high, the suggestion is likely to be
       meaningless.  */
    if (m_best_candidate)
      {
	edit_distance_t cutoff = get_cutoff (m_best_candidate_len);
	if (m_best_distance > cutoff)
	  return NULL;
    }

    /* If the goal string somehow makes it into the candidate list, offering
       it as a suggestion will be nonsensical e.g.
         'constexpr' does not name a type; did you mean 'constexpr'?
       Ultimately such suggestions are due to bugs in constructing the
       candidate list, but as a band-aid, do not offer suggestions for
       distance == 0 (where candidate == goal).  */
    if (m_best_distance == 0)
      return NULL;

    return m_best_candidate;
  }

  /* Get the closest candidate so far, without applying any filtering.  */

  candidate_t blithely_get_best_candidate () const
  {
    return m_best_candidate;
  }

  edit_distance_t get_best_distance () const { return m_best_distance; }
  size_t get_best_candidate_length () const { return m_best_candidate_len; }

 private:
  const char *m_goal;
  size_t m_goal_len;
  candidate_t m_best_candidate;
  edit_distance_t m_best_distance;
  size_t m_best_candidate_len;
};

#endif  /* GCC_SPELLCHECK_H  */
