#!/usr/bin/env ruby

$LOAD_PATH.unshift(File.dirname(File.realpath(__FILE__)) + '/../lib')
require 'pg_query'
require 'sqlint'
require 'optparse'

LIMIT = 1000

options = { limit: 1000 }
optparse = OptionParser.new do |opts|
  opts.banner = "Usage: #{File.basename($0)} [options] file.sql ..."
  opts.separator ""
  opts.separator "Options:"
  opts.on("--limit=N", Integer, "Limit checking to N errors") do |n|
    options[:limit] = n
  end
  opts.on_tail("-h", "--help", "Print this help") do
    puts opts
    exit 0
  end
  opts.on_tail("-v", "--version", "Display the version") do
    puts SQLint::VERSION
    exit 0
  end
end
optparse.parse!(ARGV)
if ARGV.empty?
  puts optparse
  exit 1
end

ERROR_TYPES = {error: "ERROR", warning: "WARNING"}

class String
  def sanitise
    gsub(/[[:cntrl:]+]/) do |bad|
      bad.codepoints.map { |c| "\\%04d" % c }.join
    end
  end
end

saw_errors = false
ARGV.each do |filename|
  File.open(filename, 'r') do |file|
    results = SQLint::Linter.new(filename, file).run.first(options[:limit])
    results.each do |lint|
      message_lines = lint.message.split("\n")
      puts [
        lint.filename,
        lint.line,
        lint.column,
        ERROR_TYPES[lint.type] + " " + message_lines.shift.sanitise
      ].join(":")
      message_lines.each do |line|
        puts "  " + line.sanitise
      end

      saw_errors ||= (lint.type == :error)
    end
  end
end

exit 1 if saw_errors
