#!/usr/bin/env ruby

require 'qed'
require 'getoptlong'

module QED

  # = QED Commandline Tool
  #
  class Command
    def self.execute
      new.execute
    end

    attr :reporter

    def initialize
      @reporter = nil
    end

    def opts
      @opts ||= GetoptLong.new(
        [ '--version',        GetoptLong::NO_ARGUMENT ],
        [ '--help',     '-h', GetoptLong::NO_ARGUMENT ],
        [ '--debug',    '-D', GetoptLong::NO_ARGUMENT ],
        [ '--verbose',  '-V', GetoptLong::NO_ARGUMENT ],
        [ '--verbatim', '-v', GetoptLong::NO_ARGUMENT ],
        [ '--summary',  '-s', GetoptLong::NO_ARGUMENT ],
        [ '--script',         GetoptLong::NO_ARGUMENT ],
        [ '--loadpath', '-I', GetoptLong::REQUIRED_ARGUMENT ]
      )
    end

    #
    def parse_options
      opts.each do |opt, arg|
        case opt
        when '--help'
          puts HELP
          exit
        when '--debug'
          $RESPECT_DEBUG = true
        when '--verbose'
          $VERBOSE = true
        when '--verbatim'
          @reporter = :verbatim
        when '--summary'
          @reporter = :summary
        when '--script'
          @reporter = :script  # psuedo-reporter
        when '--loadpath'
          libs = arg.split(/[:;]/).map{ |dir| File.expand_path(dir) }
          libs.each{|dir| $LOAD_PATH.unshift(dir)}
        end
      end
    end

    #
    #def load_rc
    #  if rcfile = Dir['.config/qed{,rc}{,.rb}'].first
    #    load(rcfile)
    #  end
    #end

    # TODO: Better way to load helpers?
    #
    #def load_helpers
    #  dirs = spec_files.map{ |file| File.join(Dir.pwd, File.dirname(file)) }
    #  dirs = dirs.select{ |dir| File.directory?(dir) }
    #  dirs.each do |dir|
    #    while dir != '/' do
    #      helper = File.join(dir, 'qed_helper.rb')
    #      load(helper) if File.exist?(helper)
    #      break if Dir.pwd == dir
    #      dir = File.dirname(dir)
    #    end
    #  end
    #end

    #
    def specs
      spec_files
    end

    #
    def spec_files
      files = ARGV.map do |pattern|
        Dir[pattern]
      end.flatten.uniq

      files = files.map do |file|
        File.directory?(file) ? Dir[File.join(file,'**','*')] : file
      end.flatten.uniq

      files = files.reject do |file| 
        %w{.yml .yaml .rb}.include?(File.extname(file))
      end

      files
    end

    #
    def output
      case reporter
      when :verbatim
        Reporter::Verbatim.new
      when :summary
        Reporter::Summary.new
      else
        nil
      end
    end

    #
    def runner
      Runner.new(specs, output)
    end

    #
    def execute
      parse_options
      #load_rc
      #load_helpers
      case reporter
      when :script
        specs.each do |spec|
          puts spec.to_script
        end
      else
        runner.check
      end
    end

    HELP = <<-END
qed [--options] [spec/tests...]

Options:
-v --verbatim   use verbatim reporter
-s --summary    use summary reporter
-V --verbose    extra verbose output
-D --debug      spec/tests will exit on error
-h --help       show this help information
   --version    show quarry version
    END

  end
end

QED::Command.execute