#!/usr/bin/env ruby
require 'rubygems'
$:.unshift(File.expand_path(File.join(File.dirname(__FILE__), "..", 'lib')))
require 'rdf/n3'
require 'rdf/ntriples'
require 'rdf/rdfxml' rescue nil
require 'rdf/rdfa' rescue nil
require 'getoptlong'
require 'open-uri'

def run(input, options)
  reader_class = RDF::Reader.for(options[:input_format].to_sym)
  raise "Reader not found for #{options[:input_format]}" unless reader_class

  prefixes = {}
  start = Time.new
  num = 0
  if options[:parse_only]
    include RDF::N3::Meta
    include RDF::N3::Parser
    puts "\nparse #{input.read}---\n\n" unless options[:quiet]
    input.rewind
    if options[:quiet]
      $stdout = StringIO.new
    end
    test(input, BRANCHES, REGEXPS)
    if options[:quiet]
      $stdout = STDOUT
      print "."
    end
  elsif options[:output_format] == :ntriples || options[:quiet]
    reader_class.new(input, :base_uri => options[:base_uri], :strict => true).each do |statement|
      num += 1
      if options[:quiet]
        #print "."
      else
       options[:output]. puts statement.to_ntriples
      end
    end
  elsif options[:output_format] == :inspect
    reader_class.new(input, :base_uri => options[:base_uri], :strict => true).each do |statement|
      num += 1
      options[:output].puts statement.inspect
    end
  else
    r = reader_class.new(input, :base_uri => options[:base_uri], :strict => true)
    g = RDF::Graph.new << r
    num = g.count
    options[:output].puts g.dump(options[:output_format], :base_uri => r.base_uri, :prefixes => r.prefixes)
  end
  puts
  secs = Time.new - start
  puts "Parsed #{num} statements in #{secs} seconds @ #{num/secs} statements/second."
rescue
  fname = input.respond_to?(:path) ? input.path : "-stdin-"
  STDERR.puts("Error in #{fname}")
  raise
end

options = {
  :validate => false,
  :strict => true,
  :output => STDOUT,
  :output_format => :ntriples,
  :input_format => :n3,
  :base_uri => "http://example.com",
}
input = nil

opts = GetoptLong.new(
  ["--dbg", GetoptLong::NO_ARGUMENT],
  ["--execute", "-e", GetoptLong::REQUIRED_ARGUMENT],
  ["--format", GetoptLong::REQUIRED_ARGUMENT],
  ["--input-format", GetoptLong::REQUIRED_ARGUMENT],
  ["--output", "-o", GetoptLong::REQUIRED_ARGUMENT],
  ["--parse-only", GetoptLong::NO_ARGUMENT],
  ["--quiet", GetoptLong::NO_ARGUMENT],
  ["--uri", GetoptLong::REQUIRED_ARGUMENT],
  ["--verbose", GetoptLong::NO_ARGUMENT]
)
opts.each do |opt, arg|
  case opt
  when '--dbg'        then ::RDF::N3::debug = true
  when '--execute'      then input = arg
  when '--format'       then options[:output_format] = arg.to_sym
  when '--input-format' then options[:input_format] = arg.to_sym
  when '--output'       then options[:output] = File.open(arg, "w")
  when '--parse-only'   then options[:parse_only] = true
  when '--quiet'        then options[:quiet] = true
  when '--uri'          then options[:base_uri] = arg
  when '--verbose'      then $verbose = true
  end
end

if ARGV.empty?
  s = input ? input : $stdin.read
  run(StringIO.new(s), options)
else
  ARGV.each do |test_file|
    run(Kernel.open(test_file), options)
  end
end
puts