// Copyright (C) 2023-2025 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 RUST_FMT_H
#define RUST_FMT_H

#include "rust-system.h"

// FIXME: How to encode Option?

namespace Rust {
namespace Fmt {

namespace ffi {

struct RustHamster
{
  const char *ptr;
  size_t len;

  std::string to_string () const;
};

/// Enum of alignments which are supported.
enum class Alignment
{
  /// The value will be aligned to the left.
  AlignLeft,
  /// The value will be aligned to the right.
  AlignRight,
  /// The value will be aligned in the center.
  AlignCenter,
  /// The value will take on a default alignment.
  AlignUnknown,
};

/// Enum for the debug hex flags.
enum class DebugHex
{
  /// The `x` flag in `{:x?}`.
  Lower,
  /// The `X` flag in `{:X?}`.
  Upper,
};

/// Enum for the sign flags.
enum class Sign
{
  /// The `+` flag.
  Plus,
  /// The `-` flag.
  Minus,
};

/// Enum describing where an argument for a format can be located.
struct Position
{
  enum class Tag
  {
    /// The argument is implied to be located at an index
    ArgumentImplicitlyIs,
    /// The argument is located at a specific index given in the format,
    ArgumentIs,
    /// The argument has a name.
    ArgumentNamed,
  };

  struct ArgumentImplicitlyIs_Body
  {
    size_t _0;
  };

  struct ArgumentIs_Body
  {
    size_t _0;
  };

  struct ArgumentNamed_Body
  {
    RustHamster _0;
  };

  Tag tag;
  union
  {
    ArgumentImplicitlyIs_Body argument_implicitly_is;
    ArgumentIs_Body argument_is;
    ArgumentNamed_Body argument_named;
  };
};

/// Range inside of a `Span` used for diagnostics when we only have access to
/// relative positions.
struct InnerSpan
{
  size_t start;
  size_t end;
};

/// A count is used for the precision and width parameters of an integer, and
/// can reference either an argument or a literal integer.
struct Count
{
  enum class Tag
  {
    /// The count is specified explicitly.
    CountIs,
    /// The count is specified by the argument with the given name.
    CountIsName,
    /// The count is specified by the argument at the given index.
    CountIsParam,
    /// The count is specified by a star (like in `{:.*}`) that refers to the
    /// argument at the given index.
    CountIsStar,
    /// The count is implied and cannot be explicitly specified.
    CountImplied,
  };

  struct CountIs_Body
  {
    size_t _0;
  };

  struct CountIsName_Body
  {
    RustHamster _0;
    InnerSpan _1;
  };

  struct CountIsParam_Body
  {
    size_t _0;
  };

  struct CountIsStar_Body
  {
    size_t _0;
  };

  Tag tag;
  union
  {
    CountIs_Body count_is;
    CountIsName_Body count_is_name;
    CountIsParam_Body count_is_param;
    CountIsStar_Body count_is_star;
  };
};

/// Specification for the formatting of an argument in the format string.
struct FormatSpec
{
  /// Optionally specified character to fill alignment with.
  const uint32_t *fill;
  /// Span of the optionally specified fill character.
  const InnerSpan *fill_span;
  /// Optionally specified alignment.
  Alignment align;
  /// The `+` or `-` flag.
  const Sign *sign;
  /// The `#` flag.
  bool alternate;
  /// The `0` flag.
  bool zero_pad;
  /// The `x` or `X` flag. (Only for `Debug`.)
  const DebugHex *debug_hex;
  /// The integer precision to use.
  Count precision;
  /// The span of the precision formatting flag (for diagnostics).
  const InnerSpan *precision_span;
  /// The string width requested for the resulting format.
  Count width;
  /// The span of the width formatting flag (for diagnostics).
  const InnerSpan *width_span;
  /// The descriptor string representing the name of the format desired for
  /// this argument, this can be empty or any number of characters, although
  /// it is required to be one word.
  RustHamster ty;
  /// The span of the descriptor string (for diagnostics).
  const InnerSpan *ty_span;
};

/// Representation of an argument specification.
struct Argument
{
  /// Where to find this argument
  Position position;
  /// The span of the position indicator. Includes any whitespace in implicit
  /// positions (`{  }`).
  InnerSpan position_span;
  /// How to format the argument
  FormatSpec format;
};

/// A piece is a portion of the format string which represents the next part
/// to emit. These are emitted as a stream by the `Parser` class.
struct Piece
{
  enum class Tag
  {
    /// A literal string which should directly be emitted
    String,
    /// This describes that formatting should process the next argument (as
    /// specified inside) for emission.
    NextArgument,
  };

  struct String_Body
  {
    RustHamster _0;
  };

  struct NextArgument_Body
  {
    Argument _0;
  };

  Tag tag;
  union
  {
    String_Body string;
    NextArgument_Body next_argument;
  };
};

struct PieceSlice
{
  const Piece *base_ptr;
  size_t len;
  size_t cap;
};

struct RustString
{
  const unsigned char *ptr;
  size_t len;
  size_t cap;
};

struct FormatArgsHandle
{
  PieceSlice piece_slice;
  RustString rust_string;
};

enum ParseMode
{
  Format = 0,
  InlineAsm,
};

extern "C" {

FormatArgsHandle
collect_pieces (const char *input, bool append_newline, ParseMode parse_mode);

FormatArgsHandle
clone_pieces (const FormatArgsHandle &);

void destroy_pieces (FormatArgsHandle);

} // extern "C"

} // namespace ffi

struct Pieces
{
  static Pieces collect (const std::string &to_parse, bool append_newline,
			 ffi::ParseMode parse_mode);
  ~Pieces ();

  Pieces (const Pieces &other);
  Pieces &operator= (const Pieces &other);

  Pieces (Pieces &&other);

  const std::vector<ffi::Piece> &get_pieces () const { return pieces_vector; }

  // {
  //   slice = clone_pieces (&other.slice);
  //   to_parse = other.to_parse;

  //   return *this;
  // }

private:
  Pieces (ffi::FormatArgsHandle handle, std::vector<ffi::Piece> &&pieces_vector)
    : pieces_vector (std::move (pieces_vector)), handle (handle)
  {}

  std::vector<ffi::Piece> pieces_vector;

  // this memory is held for FFI reasons - it needs to be released and cloned
  // precisely, so try to not access it/modify it if possible. you should
  // instead work with `pieces_vector`
  ffi::FormatArgsHandle handle;
};

} // namespace Fmt
} // namespace Rust

#endif // !RUST_FMT_H
