#!/usr/bin/env ruby

require 'open3'
require 'date'

words = if ARGV[0] == '--hard'
          puts "Playing in HARD MODE"
          File.open("easy-words.txt") { |f| f.read }
        else
          puts "Playing in EASY MODE"
          File.open("hard-words.txt") { |f| f.read }
        end.lines

ARGV.pop # needed so that `gets` works for some reason?

word = words[rand(words.size)]

prompt = File.open('prompt') { |f| f.read.gsub('{WORD}', word) }
File.open('prompt.tmp', 'w') { |f| f.write(prompt) } # easier than escaping in bash command lol


cmd = %{llama-cli -m DeepSeek*.gguf -ngl 15000 -cnv --grammar-file grammar -f prompt.tmp --repeat-penalty 1.1 --repeat-last-n 20 -c 32768 --no-display-prompt}

stdin, stdout, _ = Open3.popen2e(cmd)

file = File.open("log/#{DateTime.now.to_s}.txt", 'w')
file.write("Word: #{word}\n")

Thread.new do
  cur_line = ''
  thinks = nil
  while c = stdout.getc
    file.write(c)
    file.flush()
    if c == "\n"
      if cur_line.include?('<think>')
        thinks = 0
        puts
      elsif cur_line.include?('</think>')
        thinks = nil
        puts "\n</think>" # now we have 2 newlines
      elsif cur_line.include?('YOU WIN!!!!!') && thinks.nil?
        puts "\nGood job! The word was #{word}"
      end

      cur_line = ''
    else
      cur_line += c
    end

    if thinks.nil?
      print c
    else
      if c == ' ' || c == "\n"
        thinks += 1
        print "\rthink x#{thinks}"
      end
    end
  end
end

loop do
  line = gets
  stdin.write(line)
  file.write(line)
  file.flush()
  stdin.flush()
end