#!/usr/bin/env ruby

ERR_CHANNEL = STDERR.dup
OUT_CHANNEL = STDOUT.dup

STDERR.reopen('/dev/null', 'w')
STDOUT.reopen('/dev/null', 'w')

require 'ostruct'

OPTIONS = OpenStruct.new

def log(msg)
  if OPTIONS.logfile
    File.open(OPTIONS.logfile, 'a') { |f| f.puts "#{Time.now}: #{msg}"}
  end
  nil
end

require 'json'
require 'optparse'

begin
  OptionParser.new do |opts|
    opts.on('--vim-pid=PID') # Ignore: included only to make `ps` output more useful.
    opts.on('--logfile=NAME') do |logfile|
      OPTIONS.logfile = logfile
    end
  end.parse!
rescue => e
  log e
end

begin
  require 'command-t'
  require 'command-t/ext'
rescue LoadError => e
  load_path_modified = false
  [
    File.expand_path('../ext', File.dirname(__FILE__)),
    File.expand_path('../lib', File.dirname(__FILE__))
  ].each do |path|
    if !$LOAD_PATH.include?(path)
      $LOAD_PATH << path
      load_path_modified = true
    end
  end
  retry if load_path_modified

  # TODO: show error here instructing to run install script
  log e
  exit 1
end

def read
  line = STDIN.readline.chomp
  input = JSON[line]
  log "read: #{line}"
  input
rescue => e
  log "read: #{e} reading line: #{line.inspect}"
end

def write(payload)
  json = payload.to_json
  OUT_CHANNEL.puts json
  OUT_CHANNEL.flush
  log "wrote: #{json}"
end

log "open for business running from #{__FILE__}"

while true
  log 'loop'
  next unless input = read
  if input['cd']
    Dir.chdir(input['cd'])
    log "changed directory to #{input['cd']}"
    write({'cd' => input['cd']})
  elsif input['match']
    threads = CommandT::Util.processor_count
    scanner = OpenStruct.new(:paths => ['commandt/foo', 'commandt/bar'])
    matcher = CommandT::Matcher.new(scanner)
    results = matcher.sorted_matches_for(input['match'], :threads => threads)
    write({'results' => results})
  else
    write({'echo' => input})
  end
end
