#ifndef FLATBUFFERS_INCLUDE_CODEGEN_NAMER_H_
#define FLATBUFFERS_INCLUDE_CODEGEN_NAMER_H_

#include "flatbuffers/util.h"

namespace flatbuffers {

// Options for Namer::File.
enum class SkipFile {
  None = 0,
  Suffix = 1,
  Extension = 2,
  SuffixAndExtension = 3,
};
inline SkipFile operator&(SkipFile a, SkipFile b) {
  return static_cast<SkipFile>(static_cast<int>(a) & static_cast<int>(b));
}
// Options for Namer::Directories
enum class SkipDir {
  None = 0,
  // Skip prefixing the -o $output_path.
  OutputPath = 1,
  // Skip trailing path seperator.
  TrailingPathSeperator = 2,
  OutputPathAndTrailingPathSeparator = 3,
};
inline SkipDir operator&(SkipDir a, SkipDir b) {
  return static_cast<SkipDir>(static_cast<int>(a) & static_cast<int>(b));
}

// `Namer` applies style configuration to symbols in generated code. It manages
// casing, escapes keywords, and object API naming.
// TODO: Refactor all code generators to use this.
class Namer {
 public:
  struct Config {
    // Symbols in code.

    // Case style for flatbuffers-defined types.
    // e.g. `class TableA {}`
    Case types;
    // Case style for flatbuffers-defined constants.
    // e.g. `uint64_t ENUM_A_MAX`;
    Case constants;
    // Case style for flatbuffers-defined methods.
    // e.g. `class TableA { int field_a(); }`
    Case methods;
    // Case style for flatbuffers-defined functions.
    // e.g. `TableA* get_table_a_root()`;
    Case functions;
    // Case style for flatbuffers-defined fields.
    // e.g. `struct Struct { int my_field; }`
    Case fields;
    // Case style for flatbuffers-defined variables.
    // e.g. `int my_variable = 2`
    Case variables;
    // Case style for flatbuffers-defined variants.
    // e.g. `enum class Enum { MyVariant, }`
    Case variants;
    // Seperator for qualified enum names.
    // e.g. `Enum::MyVariant` uses `::`.
    std::string enum_variant_seperator;

    // Configures, when formatting code, whether symbols are checked against
    // keywords and escaped before or after case conversion. It does not make
    // sense to do so before, but its legacy behavior. :shrug:
    // TODO(caspern): Deprecate.
    enum class Escape {
      BeforeConvertingCase,
      AfterConvertingCase,
    };
    Escape escape_keywords;

    // Namespaces

    // e.g. `namespace my_namespace {}`
    Case namespaces;
    // The seperator between namespaces in a namespace path.
    std::string namespace_seperator;

    // Object API.
    // Native versions flatbuffers types have this prefix.
    // e.g. "" (it's usually empty string)
    std::string object_prefix;
    // Native versions flatbuffers types have this suffix.
    // e.g. "T"
    std::string object_suffix;

    // Keywords.
    // Prefix used to escape keywords. It is usually empty string.
    std::string keyword_prefix;
    // Suffix used to escape keywords. It is usually "_".
    std::string keyword_suffix;
    // The casing used for keywords when escaping. For most languages, keywords
    // are case sensitive. PHP is an instance where some keywords are case
    // insensitive.
    enum class KeywordsCasing {
      CaseSensitive,
      CaseInsensitive,
    };
    KeywordsCasing keywords_casing;

    // Files.

    // Case style for filenames. e.g. `foo_bar_generated.rs`
    Case filenames;
    // Case style for directories, e.g. `output_files/foo_bar/baz/`
    Case directories;
    // The directory within which we will generate files.
    std::string output_path;
    // Suffix for generated file names, e.g. "_generated".
    std::string filename_suffix;
    // Extension for generated files, e.g. ".cpp" or ".rs".
    std::string filename_extension;
  };
  Namer(Config config, std::set<std::string> keywords)
      : config_(config), keywords_(std::move(keywords)) {}

  virtual ~Namer() {}

  template <typename T>
  std::string Method(const T& s) const {
    return Method(s.name);
  }

  virtual std::string Method(const std::string& pre, const std::string& mid,
                             const std::string& suf) const {
    return Format(pre + "_" + mid + "_" + suf, config_.methods);
  }
  virtual std::string Method(const std::string& pre,
                             const std::string& suf) const {
    return Format(pre + "_" + suf, config_.methods);
  }
  virtual std::string Method(const std::string& s) const {
    return Format(s, config_.methods);
  }

  virtual std::string Constant(const std::string& s) const {
    return Format(s, config_.constants);
  }

  virtual std::string Function(const std::string& s) const {
    return Format(s, config_.functions);
  }

  virtual std::string Variable(const std::string& s) const {
    return Format(s, config_.variables);
  }

  template <typename T>
  std::string Variable(const std::string& p, const T& s) const {
    return Format(p + "_" + s.name, config_.variables);
  }
  virtual std::string Variable(const std::string& p,
                               const std::string& s) const {
    return Format(p + "_" + s, config_.variables);
  }

  virtual std::string Namespace(const std::string& s) const {
    return Format(s, config_.namespaces);
  }

  virtual std::string Namespace(const std::vector<std::string>& ns) const {
    std::string result;
    for (auto it = ns.begin(); it != ns.end(); it++) {
      if (it != ns.begin()) result += config_.namespace_seperator;
      result += Namespace(*it);
    }
    return result;
  }

  virtual std::string NamespacedType(const std::vector<std::string>& ns,
                                     const std::string& s) const {
    return (ns.empty() ? "" : (Namespace(ns) + config_.namespace_seperator)) +
           Type(s);
  }

  // Returns `filename` with the right casing, suffix, and extension.
  virtual std::string File(const std::string& filename,
                           SkipFile skips = SkipFile::None) const {
    const bool skip_suffix = (skips & SkipFile::Suffix) != SkipFile::None;
    const bool skip_ext = (skips & SkipFile::Extension) != SkipFile::None;
    return ConvertCase(filename, config_.filenames, Case::kUpperCamel) +
           (skip_suffix ? "" : config_.filename_suffix) +
           (skip_ext ? "" : config_.filename_extension);
  }
  template <typename T>
  std::string File(const T& f, SkipFile skips = SkipFile::None) const {
    return File(f.name, skips);
  }

  // Formats `directories` prefixed with the output_path and joined with the
  // right seperator. Output path prefixing and the trailing separator may be
  // skiped using `skips`.
  // Callers may want to use `EnsureDirExists` with the result.
  // input_case is used to tell how to modify namespace. e.g. kUpperCamel will
  // add a underscode between case changes, so MyGame turns into My_Game
  // (depending also on the output_case).
  virtual std::string Directories(const std::vector<std::string>& directories,
                                  SkipDir skips = SkipDir::None,
                                  Case input_case = Case::kUpperCamel) const {
    const bool skip_output_path =
        (skips & SkipDir::OutputPath) != SkipDir::None;
    const bool skip_trailing_seperator =
        (skips & SkipDir::TrailingPathSeperator) != SkipDir::None;
    std::string result = skip_output_path ? "" : config_.output_path;
    for (auto d = directories.begin(); d != directories.end(); d++) {
      result += ConvertCase(*d, config_.directories, input_case);
      result.push_back(kPathSeparator);
    }
    if (skip_trailing_seperator && !result.empty()) result.pop_back();
    return result;
  }

  virtual std::string NormalizeKeywordCase(const std::string& name) const {
    if (config_.keywords_casing == Config::KeywordsCasing::CaseInsensitive) {
      return ConvertCase(name, Case::kAllLower);
    } else {
      return name;
    }
  }

  virtual std::string EscapeKeyword(const std::string& name) const {
    if (keywords_.find(NormalizeKeywordCase(name)) == keywords_.end()) {
      return name;
    } else {
      return config_.keyword_prefix + name + config_.keyword_suffix;
    }
  }

  virtual std::string Type(const std::string& s) const {
    return Format(s, config_.types);
  }
  virtual std::string Type(const std::string& t, const std::string& s) const {
    return Format(t + "_" + s, config_.types);
  }

  virtual std::string ObjectType(const std::string& s) const {
    return config_.object_prefix + Type(s) + config_.object_suffix;
  }

  virtual std::string Field(const std::string& s) const {
    return Format(s, config_.fields);
  }

  virtual std::string Variant(const std::string& s) const {
    return Format(s, config_.variants);
  }

  virtual std::string Format(const std::string& s, Case casing) const {
    if (config_.escape_keywords == Config::Escape::BeforeConvertingCase) {
      return ConvertCase(EscapeKeyword(s), casing, Case::kLowerCamel);
    } else {
      return EscapeKeyword(ConvertCase(s, casing, Case::kLowerCamel));
    }
  }

  // Denamespaces a string (e.g. The.Quick.Brown.Fox) by returning the last part
  // after the `delimiter` (Fox) and placing the rest in `namespace_prefix`
  // (The.Quick.Brown).
  virtual std::string Denamespace(const std::string& s,
                                  std::string& namespace_prefix,
                                  const char delimiter = '.') const {
    const size_t pos = s.find_last_of(delimiter);
    if (pos == std::string::npos) {
      namespace_prefix = "";
      return s;
    }
    namespace_prefix = s.substr(0, pos);
    return s.substr(pos + 1);
  }

  // Same as above, but disregards the prefix.
  virtual std::string Denamespace(const std::string& s,
                                  const char delimiter = '.') const {
    std::string prefix;
    return Denamespace(s, prefix, delimiter);
  }

  const Config config_;
  const std::set<std::string> keywords_;
};

}  // namespace flatbuffers

#endif  // FLATBUFFERS_INCLUDE_CODEGEN_NAMER_H_
