class Ollama::Handlers::Say

def call(response)

def call(response)
  if @output.closed?
    wait_output_pid
    @output     = open_output
    @output_pid = @output.pid
  end
  if content = response.response || response.message&.content
    @output.print content
  end
  response.done and @output.close
  self
end

def command(voice:, interactive:)

def command(voice:, interactive:)
  command = [ 'say' ]
  voice and command.concat([ '-v', voice ])
  case interactive
  when true
    command << '-i'
  when String
    command << '--interactive=%s' % interactive
  end
  command
end

def initialize(output: nil, voice: 'Samantha', interactive: nil)

def initialize(output: nil, voice: 'Samantha', interactive: nil)
  @voice       = voice
  @interactive = interactive
  super(output:)
  unless output
    @output = open_output
    @output_pid = @output.pid
  end
end

def open_output

def open_output
  io = IO.popen(Shellwords.join(command(voice:, interactive:)), 'w')
  io.sync = true
  io
end

def wait_output_pid

def wait_output_pid
  @output_pid or return
  Process.wait(@output_pid, Process::WNOHANG | Process::WUNTRACED)
rescue Errno::ECHILD
end