/* 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/>. */

#include "rust-parse.h"
#include "rust-linemap.h"
#include "rust-diagnostics.h"
#include "rust-token.h"
#include "rust-attribute-values.h"

namespace Rust {

std::string
extract_module_path (const AST::AttrVec &inner_attrs,
		     const AST::AttrVec &outer_attrs, const std::string &name)
{
  AST::Attribute path_attr = AST::Attribute::create_empty ();
  for (const auto &attr : inner_attrs)
    {
      if (attr.get_path ().as_string () == Values::Attributes::PATH)
	{
	  path_attr = attr;
	  break;
	}
    }

  // Here, we found a path attribute, but it has no associated string. This is
  // invalid
  if (!path_attr.is_empty () && !path_attr.has_attr_input ())
    {
      rust_error_at (
	path_attr.get_locus (),
	"path attributes must contain a filename: %<#[path = \"file\"]%>");
      return name;
    }

  for (const auto &attr : outer_attrs)
    {
      if (attr.get_path ().as_string () == Values::Attributes::PATH)
	{
	  path_attr = attr;
	  break;
	}
    }

  // We didn't find a path attribute. This is not an error, there simply isn't
  // one present
  if (path_attr.is_empty ())
    return name;

  // Here, we found a path attribute, but it has no associated string. This is
  // invalid
  if (!path_attr.has_attr_input ())
    {
      rust_error_at (
	path_attr.get_locus (),
	"path attributes must contain a filename: %<#[path = \"file\"]%>");
      return name;
    }

  auto path_value = path_attr.get_attr_input ().as_string ();

  // At this point, the 'path' is of the following format: '= "<file.rs>"'
  // We need to remove the equal sign and only keep the actual filename.
  // In order to do this, we can simply go through the string until we find
  // a character that is not an equal sign or whitespace
  auto filename_begin = path_value.find_first_not_of ("=\t ");

  // If the path consists of only whitespace, then we have an error
  if (filename_begin == std::string::npos)
    {
      rust_error_at (
	path_attr.get_locus (),
	"path attributes must contain a filename: %<#[path = \"file\"]%>");
      return name;
    }

  auto path = path_value.substr (filename_begin);

  // On windows, the path might mix '/' and '\' separators. Replace the
  // UNIX-like separators by MSDOS separators to make sure the path will resolve
  // properly.
  //
  // Source: rustc compiler
  // (https://github.com/rust-lang/rust/blob/9863bf51a52b8e61bcad312f81b5193d53099f9f/compiler/rustc_expand/src/module.rs#L174)
#if defined(HAVE_DOS_BASED_FILE_SYSTEM)
  std::replace (path.begin (), path.end (), '/', '\\');
#endif /* HAVE_DOS_BASED_FILE_SYSTEM */

  return path;
}

template <typename T>
static bool
contains (std::vector<T> &vec, T elm)
{
  return std::find (vec.begin (), vec.end (), elm) != vec.end ();
}

/**
 * Avoid UB by calling .front() and .back() on empty containers...
 */

template <typename T>
static const T *
get_back_ptr (const std::vector<std::unique_ptr<T>> &values)
{
  if (values.empty ())
    return nullptr;

  return values.back ().get ();
}

template <typename T>
static const T *
get_front_ptr (const std::vector<std::unique_ptr<T>> &values)
{
  if (values.empty ())
    return nullptr;

  return values.front ().get ();
}

static bool
peculiar_fragment_match_compatible_fragment (
  const AST::MacroFragSpec &last_spec, const AST::MacroFragSpec &spec,
  location_t match_locus)
{
  static std::unordered_map<AST::MacroFragSpec::Kind,
			    std::vector<AST::MacroFragSpec::Kind>>
    fragment_follow_set
    = {{AST::MacroFragSpec::PATH, {AST::MacroFragSpec::BLOCK}},
       {AST::MacroFragSpec::TY, {AST::MacroFragSpec::BLOCK}},
       {AST::MacroFragSpec::VIS,
	{AST::MacroFragSpec::IDENT, AST::MacroFragSpec::TY,
	 AST::MacroFragSpec::PATH}}};

  auto is_valid
    = contains (fragment_follow_set[last_spec.get_kind ()], spec.get_kind ());

  if (!is_valid)
    rust_error_at (match_locus,
		   "fragment specifier %qs is not allowed after %qs fragments",
		   spec.as_string ().c_str (), last_spec.as_string ().c_str ());

  return is_valid;
}

static bool
peculiar_fragment_match_compatible (const AST::MacroMatchFragment &last_match,
				    const AST::MacroMatch &match)
{
  static std::unordered_map<AST::MacroFragSpec::Kind, std::vector<TokenId>>
    follow_set
    = {{AST::MacroFragSpec::EXPR, {MATCH_ARROW, COMMA, SEMICOLON}},
       {AST::MacroFragSpec::STMT, {MATCH_ARROW, COMMA, SEMICOLON}},
       {AST::MacroFragSpec::PAT, {MATCH_ARROW, COMMA, EQUAL, PIPE, IF, IN}},
       {AST::MacroFragSpec::PATH,
	{MATCH_ARROW, COMMA, EQUAL, PIPE, SEMICOLON, COLON, RIGHT_ANGLE,
	 RIGHT_SHIFT, LEFT_SQUARE, LEFT_CURLY, AS, WHERE}},
       {AST::MacroFragSpec::TY,
	{MATCH_ARROW, COMMA, EQUAL, PIPE, SEMICOLON, COLON, RIGHT_ANGLE,
	 RIGHT_SHIFT, LEFT_SQUARE, LEFT_CURLY, AS, WHERE}},
       {AST::MacroFragSpec::VIS,
	{COMMA,
	 IDENTIFIER,
	 LEFT_PAREN,
	 LEFT_SQUARE,
	 EXCLAM,
	 ASTERISK,
	 AMP,
	 LOGICAL_AND,
	 QUESTION_MARK,
	 LIFETIME,
	 LEFT_ANGLE,
	 LEFT_SHIFT,
	 UNDERSCORE,
	 ABSTRACT,
	 AS,
	 ASYNC,
	 AUTO,
	 BECOME,
	 BOX,
	 BREAK,
	 CONST,
	 CONTINUE,
	 CRATE,
	 DO,
	 DYN,
	 ELSE,
	 ENUM_KW,
	 EXTERN_KW,
	 FALSE_LITERAL,
	 FINAL_KW,
	 FN_KW,
	 FOR,
	 IF,
	 IMPL,
	 IN,
	 LET,
	 LOOP,
	 MACRO,
	 MATCH_KW,
	 MOD,
	 MOVE,
	 MUT,
	 OVERRIDE_KW,
	 PUB,
	 REF,
	 RETURN_KW,
	 SELF_ALIAS,
	 SELF,
	 STATIC_KW,
	 STRUCT_KW,
	 SUPER,
	 TRAIT,
	 TRUE_LITERAL,
	 TRY,
	 TYPE,
	 TYPEOF,
	 UNSAFE,
	 UNSIZED,
	 USE,
	 VIRTUAL,
	 WHERE,
	 WHILE,
	 YIELD}}};

  location_t error_locus = match.get_match_locus ();
  std::string kind_str = "fragment";
  auto &allowed_toks = follow_set[last_match.get_frag_spec ().get_kind ()];

  // There are two behaviors to handle here: If the follow-up match is a token,
  // we want to check if it is allowed.
  // If it is a fragment, repetition or matcher then we know that it will be
  // an error.
  // For repetitions and matchers we want to extract a proper location to report
  // the error.
  switch (match.get_macro_match_type ())
    {
    case AST::MacroMatch::Tok:
      {
	auto tok = static_cast<const AST::Token *> (&match);
	if (contains (allowed_toks, tok->get_id ()))
	  return true;
	kind_str = "token `"
		   + std::string (get_token_description (tok->get_id ())) + "`";
	error_locus = tok->get_match_locus ();
	break;
      }
      break;
    case AST::MacroMatch::Repetition:
      {
	auto repetition
	  = static_cast<const AST::MacroMatchRepetition *> (&match);
	auto &matches = repetition->get_matches ();
	auto first_frag = get_front_ptr (matches);
	if (first_frag)
	  return peculiar_fragment_match_compatible (last_match, *first_frag);
	break;
      }
    case AST::MacroMatch::Matcher:
      {
	auto matcher = static_cast<const AST::MacroMatcher *> (&match);
	auto first_token = matcher->get_delim_type ();
	TokenId delim_id;
	switch (first_token)
	  {
	  case AST::PARENS:
	    delim_id = LEFT_PAREN;
	    break;
	  case AST::SQUARE:
	    delim_id = LEFT_SQUARE;
	    break;
	  case AST::CURLY:
	    delim_id = LEFT_CURLY;
	    break;
	  default:
	    rust_unreachable ();
	    break;
	  }
	if (contains (allowed_toks, delim_id))
	  return true;
	kind_str = "token `" + std::string (get_token_description (delim_id))
		   + "` at start of matcher";
	error_locus = matcher->get_match_locus ();
	break;
      }
    case AST::MacroMatch::Fragment:
      {
	auto last_spec = last_match.get_frag_spec ();
	auto fragment = static_cast<const AST::MacroMatchFragment *> (&match);
	if (last_spec.has_follow_set_fragment_restrictions ())
	  return peculiar_fragment_match_compatible_fragment (
	    last_spec, fragment->get_frag_spec (), match.get_match_locus ());
      }
      break;
    }

  rust_error_at (error_locus, "%s is not allowed after %qs fragment",
		 kind_str.c_str (),
		 last_match.get_frag_spec ().as_string ().c_str ());
  auto allowed_toks_str
    = "`" + std::string (get_token_description (allowed_toks[0])) + "`";
  for (size_t i = 1; i < allowed_toks.size (); i++)
    allowed_toks_str
      += ", `" + std::string (get_token_description (allowed_toks[i])) + "`";

  rust_inform (error_locus, "allowed tokens are %s", allowed_toks_str.c_str ());

  return false;
}

bool
is_match_compatible (const AST::MacroMatch &last_match,
		     const AST::MacroMatch &match)
{
  const AST::MacroMatch *new_last = nullptr;

  // We want to "extract" the concerning matches. In cases such as matchers and
  // repetitions, we actually store multiple matchers, but are only concerned
  // about the follow-set ambiguities of certain elements.
  // There are some cases where we can short-circuit the algorithm: There will
  // never be restrictions on token literals, or on certain fragments which do
  // not have a set of follow-restrictions.

  switch (last_match.get_macro_match_type ())
    {
    // This is our main stop condition: When we are finally looking at the
    // last match (or its actual last component), and it is a fragment, it
    // may contain some follow up restrictions.
    case AST::MacroMatch::Fragment:
      {
	auto fragment
	  = static_cast<const AST::MacroMatchFragment *> (&last_match);
	if (fragment->get_frag_spec ().has_follow_set_restrictions ())
	  return peculiar_fragment_match_compatible (*fragment, match);
	else
	  return true;
      }
    case AST::MacroMatch::Repetition:
      {
	// A repetition on the left hand side means we want to make sure the
	// last match of the repetition is compatible with the new match
	auto repetition
	  = static_cast<const AST::MacroMatchRepetition *> (&last_match);
	new_last = get_back_ptr (repetition->get_matches ());
	// If there are no matches in the matcher, then it can be followed by
	// anything
	if (!new_last)
	  return true;
	break;
      }
    case AST::MacroMatch::Matcher:
    case AST::MacroMatch::Tok:
      return true;
    }

  rust_assert (new_last);

  // We check recursively until we find a terminating condition
  // FIXME: Does expansion depth/limit matter here?
  return is_match_compatible (*new_last, match);
}
} // namespace Rust
