# OAuth 1.0 header generation library
module SimpleOAuth
  # Error raised when parsing a malformed OAuth Authorization header
  class ParseError < StandardError
  end

  # Error raised when invalid options are passed to Header
  class InvalidOptionsError < StandardError
  end

  # OAuth percent-encoding utilities
  module Encoding
    # Characters that don't need to be escaped per OAuth spec
    UNRESERVED_CHARS: Regexp

    # Percent-encodes a value according to OAuth specification
    def escape: (String | _ToS value) -> String

    # Alias for escape
    def encode: (String | _ToS value) -> String

    # Decodes a percent-encoded value
    def unescape: (String | _ToS value) -> String

    # Alias for unescape
    def decode: (String | _ToS value) -> String

    # Module-level methods (via extend self)
    def self.escape: (String | _ToS value) -> String
    def self.encode: (String | _ToS value) -> String
    def self.unescape: (String | _ToS value) -> String
    def self.decode: (String | _ToS value) -> String
  end

  # Generates OAuth 1.0 Authorization headers for HTTP requests
  class Header
    # OAuth header scheme prefix
    OAUTH_SCHEME: String

    # Prefix for OAuth parameters
    OAUTH_PREFIX: String

    # Default signature method per RFC 5849
    DEFAULT_SIGNATURE_METHOD: String

    # OAuth version
    OAUTH_VERSION: String

    # Valid OAuth attribute keys that can be included in the header
    ATTRIBUTE_KEYS: Array[Symbol]

    # Keys that are used internally but should not appear in attributes
    IGNORED_KEYS: Array[Symbol]

    # Valid keys when parsing OAuth parameters (ATTRIBUTE_KEYS + signature)
    PARSE_KEYS: Array[Symbol]

    # Type aliases for clarity
    type oauth_key = :body_hash | :callback | :consumer_key | :nonce | :signature_method | :timestamp | :token | :verifier | :version
    type ignored_key = :consumer_secret | :token_secret | :signature | :realm | :ignore_extra_keys
    type signature_method = "HMAC-SHA1" | "HMAC-SHA256" | "RSA-SHA1" | "RSA-SHA256" | "PLAINTEXT"
    type params_hash = Hash[String | Symbol, untyped]
    type oauth_options = Hash[Symbol, untyped]
    type signed_attributes_hash = Hash[Symbol, untyped]

    # The HTTP method for the request
    attr_reader method: String

    # The request parameters to be signed
    attr_reader params: params_hash

    # The raw request body for oauth_body_hash computation
    attr_reader body: String?

    # The OAuth options including credentials and signature
    attr_reader options: oauth_options

    # Class methods from ClassMethods module
    extend ClassMethods

    # Encoding methods from Encoding module
    extend Encoding

    # Percent-encodes a value according to OAuth specification
    def self.escape: (String | _ToS value) -> String

    # Alias for escape
    def self.encode: (String | _ToS value) -> String

    # Decodes a percent-encoded value
    def self.unescape: (String | _ToS value) -> String

    # Alias for unescape
    def self.decode: (String | _ToS value) -> String

    # Creates a new OAuth header
    def initialize: (String | Symbol method, String | URI::Generic url, params_hash params, ?oauth_options | String oauth, ?String? body) -> void

    # Returns the normalized URL without query string or fragment
    def url: () -> String

    # Returns the OAuth Authorization header string
    def to_s: () -> String

    # Validates the signature in the header against the provided secrets
    def valid?: (?oauth_options secrets) -> bool

    # Returns the OAuth attributes including the signature
    def signed_attributes: () -> signed_attributes_hash

    private

    # Internal URI instance
    @uri: URI::Generic

    # Normalizes and parses a URL into a URI object
    def normalize_uri: (String | URI::Generic url) -> URI::Generic

    # Builds OAuth options from input (hash or header string)
    def build_options: (oauth_options | String oauth, String? body) -> oauth_options

    # Builds the normalized OAuth attributes string for the Authorization header
    def normalized_attributes: () -> String

    # Extracts valid OAuth attributes from options (excludes realm per RFC 5849)
    def attributes: () -> signed_attributes_hash

    # Validates that no unknown keys are present in options
    def validate_option_keys!: () -> void

    # Returns OAuth attributes including realm for Authorization header output
    def header_attributes: () -> signed_attributes_hash

    # Extracts query parameters from the request URL
    def url_params: () -> Array[untyped]

    # Computes the OAuth signature using the configured signature method
    def signature: () -> String

    # Builds the secret string from consumer and token secrets
    def secret: () -> String

    # Builds the signature base string from method, URL, and params
    def signature_base: () -> String

    # Normalizes and sorts all request parameters for signing
    def normalized_params: () -> String

    # Collects all parameters to include in signature
    def signature_params: () -> Array[untyped]
  end
end

# Version module
module SimpleOauth
  # The current version of the SimpleOAuth gem
  VERSION: String
end
