///|
pub(all) enum Argument {
  Text(String)
  Number(Int)
} derive(Debug, Eq)

///|
/// The kind of selector represented by a choice expression.
pub(all) enum ChoiceKind {
  Select
  Plural
  SelectOrdinal
} derive(Debug, Eq)

///|
/// Describes how an argument is consumed by a message.
pub(all) enum ArgumentRole {
  Interpolation
  SelectSelector
  CardinalSelector
  OrdinalSelector
} derive(Debug, Eq)

///|
/// A one-based source location together with its zero-based character offset.
pub(all) struct SourcePosition {
  offset : Int
  line : Int
  column : Int
} derive(Debug, Eq)

///|
/// A half-open range in a message template.
pub(all) struct SourceSpan {
  start : SourcePosition
  end : SourcePosition
} derive(Debug, Eq)

///|
/// A stable, serializable parser diagnostic.
pub(all) struct MessageDiagnostic {
  code : String
  message : String
  position : SourcePosition
} derive(Debug, Eq)

///|
pub struct Message {
  nodes : Array[MessageNode]
} derive(Debug)

///|
pub(all) enum MessageNode {
  TextNode(String)
  ArgumentNode(String)
  PoundNode
  ChoiceNode(String, String, Map[String, Array[MessageNode]])
} derive(Debug)

///|
pub(all) suberror MessageError {
  ParseError(position~ : Int, message~ : String)
  InvalidCatalog(String)
  InvalidLocale(String)
  InvalidCommand(String)
  EvaluationLimit(Int)
  MissingArgument(String)
  WrongArgumentType(String)
  MissingChoice(String)
} derive(Debug, Eq)

///|
/// A single use of an argument in a parsed message.
pub(all) struct ArgumentUse {
  name : String
  roles : Array[ArgumentRole]
  occurrences : Int
} derive(Debug, Eq)

///|
/// Structural information collected from a parsed message.
pub(all) struct MessageAnalysis {
  arguments : Array[ArgumentUse]
  node_count : Int
  text_node_count : Int
  argument_node_count : Int
  choice_node_count : Int
  pound_node_count : Int
  maximum_depth : Int
} derive(Debug, Eq)

///|
pub struct Catalog {
  locale : String
  entries : Map[String, String]
} derive(Debug)

///|
/// Summary information for one catalog.
pub(all) struct CatalogStats {
  locale : String
  key_count : Int
  template_count : Int
  valid_template_count : Int
  invalid_template_count : Int
  argument_count : Int
  choice_count : Int
} derive(Debug, Eq)

///|
/// Key-level difference between two catalogs.
pub(all) struct CatalogDiff {
  reference_locale : String
  translation_locale : String
  shared_keys : Array[String]
  missing_keys : Array[String]
  extra_keys : Array[String]
} derive(Debug, Eq)

///|
/// Analysis for a single catalog entry.
pub(all) struct CatalogEntryAnalysis {
  key : String
  template : String
  valid : Bool
  diagnostic : MessageDiagnostic?
  message : MessageAnalysis?
} derive(Debug)

///|
/// A builder for constructing catalogs without exposing mutable internals.
pub struct CatalogBuilder {
  locale : String
  entries : Map[String, String]
}

///|
/// How duplicate keys should be handled while combining catalogs.
pub(all) enum CatalogMergePolicy {
  KeepExisting
  ReplaceExisting
  RejectDuplicate
} derive(Debug, Eq)

///|
/// Result of a catalog coverage calculation.
pub(all) struct CatalogCoverage {
  reference_keys : Int
  translated_keys : Int
  missing_keys : Int
  extra_keys : Int
  coverage_percent : Int
} derive(Debug, Eq)

///|
/// One choice expression found in a message.
pub(all) struct ChoiceUse {
  argument : String
  kind : ChoiceKind
  selectors : Array[String]
  depth : Int
  ordinal : Int
} derive(Debug, Eq)

///|
/// Full semantic signature used by catalog linting.
pub(all) struct MessageSignature {
  arguments : Array[ArgumentUse]
  choices : Array[ChoiceUse]
} derive(Debug, Eq)

///|
/// Severity assigned to a catalog lint issue.
pub(all) enum LintSeverity {
  Error
  Warning
  Information
} derive(Debug, Eq)

///|
/// Policy switches for catalog linting.
pub(all) struct LintOptions {
  report_extra_keys : Bool
  report_extra_arguments : Bool
  report_extra_selectors : Bool
  require_locale_categories : Bool
} derive(Debug, Eq)

///|
/// Aggregate lint counts.
pub(all) struct LintSummary {
  errors : Int
  warnings : Int
  information : Int
  total : Int
} derive(Debug, Eq)

///|
pub struct LintIssue {
  severity : LintSeverity
  code : String
  key : String
  message : String
  argument : String?
  selector : String?
} derive(Debug, Eq)

///|
pub struct LintReport {
  reference_locale : String
  locale : String
  issues : Array[LintIssue]
} derive(Debug)

///|
/// A message template together with the catalog that supplied it.
pub(all) struct ResolvedMessage {
  key : String
  requested_locale : String
  resolved_locale : String
  template : String
  used_fallback : Bool
} derive(Debug, Eq)

///|
/// Detailed result returned after translation and formatting.
pub(all) struct TranslationResult {
  key : String
  requested_locale : String
  resolved_locale : String
  value : String
  used_fallback : Bool
} derive(Debug, Eq)

///|
/// Behavior used by the configurable formatter when an argument is absent.
pub(all) enum MissingArgumentBehavior {
  RaiseError
  KeepPlaceholder
  ReplaceWithEmpty
} derive(Debug, Eq)

///|
/// Runtime options for message evaluation.
pub(all) struct FormatOptions {
  missing_argument : MissingArgumentBehavior
  maximum_depth : Int
} derive(Debug, Eq)

///|
/// Kind of evaluation event emitted by `format_with_trace`.
pub(all) enum FormatEventKind {
  EmitText
  EmitArgument
  EmitPound
  SelectBranch
} derive(Debug, Eq)

///|
/// One deterministic event from message evaluation.
pub(all) struct FormatEvent {
  kind : FormatEventKind
  depth : Int
  path : String
  argument : String?
  selector : String?
  output : String
} derive(Debug, Eq)

///|
/// Formatted value plus a deterministic evaluation trace.
pub(all) struct FormattedMessage {
  value : String
  events : Array[FormatEvent]
} derive(Debug, Eq)

///|
/// Explanation of plural branch selection.
pub(all) struct PluralSelection {
  locale : String
  value : Int
  ordinal : Bool
  category : String
  exact_selector : String
  selected_selector : String
  used_exact : Bool
  used_other : Bool
} derive(Debug, Eq)

///|
/// Example values discovered for one plural category.
pub(all) struct PluralExamples {
  category : String
  values : Array[Int]
} derive(Debug, Eq)

///|
pub struct Translator {
  default_locale : String
  fallback_locale : String
  catalogs : Map[String, Catalog]
} derive(Debug)

///|
/// Text direction associated with a locale.
pub(all) enum TextDirection {
  LeftToRight
  RightToLeft
} derive(Debug, Eq)

///|
/// Parsed and normalized locale identifier.
pub(all) struct LocaleId {
  original : String
  canonical : String
  language : String
  script : String?
  region : String?
  variants : Array[String]
} derive(Debug, Eq)

///|
/// Plural rule set selected for a locale.
pub(all) enum PluralRuleFamily {
  OtherOnly
  English
  Russian
  Arabic
} derive(Debug, Eq)

///|
/// Metadata used by the runtime and linter for a supported locale.
pub(all) struct LocaleProfile {
  locale : LocaleId
  direction : TextDirection
  cardinal_family : PluralRuleFamily
  ordinal_family : PluralRuleFamily
  cardinal_categories : Array[String]
  ordinal_categories : Array[String]
} derive(Debug, Eq)

///|
/// Human-facing metadata for one explicitly supported base locale.
pub(all) struct LocaleSupport {
  language : String
  english_name : String
  native_name : String
  direction : TextDirection
  cardinal_categories : Array[String]
  ordinal_categories : Array[String]
} derive(Debug, Eq)

///|
/// Result of negotiating requested and available locales.
pub(all) struct LocaleNegotiation {
  requested : String
  candidates : Array[String]
  available : Array[String]
  matched : String?
  used_default : Bool
} derive(Debug, Eq)

///|
/// Presence information for one key across a catalog set.
pub(all) struct CatalogMatrixRow {
  key : String
  present_locales : Array[String]
  missing_locales : Array[String]
} derive(Debug, Eq)

///|
/// Cross-locale catalog coverage matrix.
pub(all) struct CatalogMatrix {
  reference_locale : String
  locales : Array[String]
  rows : Array[CatalogMatrixRow]
} derive(Debug, Eq)

///|
/// Stable command names understood by the pure CLI parser.
pub(all) enum CliCommandKind {
  Validate
  Diff
  Render
  Help
} derive(Debug, Eq)

///|
/// Parsed CLI request independent of file-system access.
pub(all) struct CliRequest {
  kind : CliCommandKind
  paths : Array[String]
  locale : String?
  key : String?
  arguments : Map[String, Argument]
  json : Bool
} derive(Debug, Eq)

///|
/// Result returned by the pure CLI execution layer.
pub(all) struct CliOutput {
  exit_code : Int
  stdout : String
  stderr : String
} derive(Debug, Eq)