#!/usr/bin/env ruby
#
# A console interface for interacting with the Ollama API.
#
# This script provides an interactive Ruby console (IRB) pre-configured with an
# Ollama client instance, enabling direct experimentation with the Ollama API.
# It automatically loads the Ollama client with the appropriate base URL, which
# can be configured via environment variables.
#
# Environment Variables:
#   - OLLAMA_URL: The base URL of the Ollama API server (e.g., 'http://localhost:11434').
#   - OLLAMA_HOST: Fallback host for constructing the base URL if OLLAMA_URL is not set.
#
# The script will:
# - Initialize an Ollama client with the configured base URL
# - Start an IRB session with the client available as the `ollama` variable
# - Display version and connection information
# - Show available API methods via `ollama.help`

require 'ollama'
include Ollama
require 'irb'
require 'irb/history'

# The base_url method returns the Ollama API base URL.
#
# It first checks for the OLLAMA_URL environment variable.
# If not set, it defaults to 'http://' followed by the OLLAMA_HOST environment variable.
#
# @return [ String ] the base URL for the Ollama API
def base_url
  ENV['OLLAMA_URL'] || 'http://%s' % ENV.fetch('OLLAMA_HOST')
end

# The client_config method retrieves and merges client configuration settings.
#
# This method fetches the base URL from the instance variable and combines it
# with configuration data parsed from the OLLAMA_CLIENT environment variable.
# If the environment variable is not set, it defaults to an empty JSON object.
#
# @return [ Hash ] a hash containing the merged configuration settings
def client_config
  Client::Config[
    { base_url:, api_key: } | JSON(ENV.fetch('OLLAMA_CLIENT', '{}')).transform_keys(&:to_sym)
  ]
end

# Retrieves the Ollama API key from the environment variable OLLAMA_API_KEY.
#
# @return [ String, nil ] the API key value or nil if the environment variable
#   is not set
def api_key
  ENV['OLLAMA_API_KEY']
end

# The ollama method provides access to a configured Ollama client instance.
#
# This method initializes and returns a singleton instance of the Ollama client,
# using the base URL specified in the base_url parameter. If an instance already
# exists, it returns the cached version instead of creating a new one.
#
# @return [ Ollama::Client ] a configured Ollama client instance
def ollama
  $ollama ||= Client.configure_with(client_config)
end

# The model method retrieves the Ollama model name from the environment
#
# This method returns the name of the Ollama model to be used for API requests,
# falling back to a default value of 'llama3.1' if the OLLAMA_MODEL environment
# variable is not set.
#
# @return [ String ] the name of the Ollama model to use, either from the
#         OLLAMA_MODEL environment variable or the default 'llama3.1'
def model
  ENV.fetch('OLLAMA_MODEL', 'llama3.1')
end

# The options method retrieves and parses model options from the environment.
#
# This method fetches the OLLAMA_MODEL_OPTIONS environment variable, parses it
# as JSON, and converts it into an Ollama::Options object for use with model
# commands.
#
# @return [ Ollama::Options ] an options object initialized with values from
#   the environment
def options
  Ollama::Options.from_hash(JSON(ENV.fetch('OLLAMA_MODEL_OPTIONS', '{}')))
end

IRB.setup nil
IRB.conf[:MAIN_CONTEXT] = IRB::Irb.new.context
IRB.conf[:HISTORY_FILE] = File.join(ENV.fetch('HOME'), '.ollama_console-history')
IRB.conf[:SAVE_HISTORY] = 1000
require 'irb/ext/multi-irb'
if io = IRB.conf[:MAIN_CONTEXT].io and io.support_history_saving?
  io.load_history
  at_exit { io.save_history }
end
puts "Now connected to ollama server, version %s, at %s" % [
  Term::ANSIColor.bold { ollama.version.version },
  Term::ANSIColor.hyperlink(ollama.base_url) { ollama.base_url },
]
ollama.help
IRB.irb nil, ollama
