# Support libraries
require 'rbconfig'

require 'facets'
require 'consoleapp'
#require 'console/command'

require 'facet/gem/self/active'

require 'reap/reap'


class ReapCommand < Console::Command

  # to do first for every task
  #def command_setup
  #  $PROJECT_INFO = ProjectInfo.new( $PROJECT_FILE )
  #end

  # Options

  # verbose mode
  def __verbose ; $VERBOSE = true ; end
  alias_method :_V, :__verbose

  # option to display help
  def __force ; $FORCE = true ; end
  alias_method :_f, :__force

  # pretend mode (under construction)
  def __pretend; $PRETEND = true ; end
  alias_method :_P, :__pretend

  # debug mode (under construction)
  def __debug; $DEBUG = true ; end
  alias_method :_D, :__debug

  def __password( pass ); $PASSWORD =  pass ; end
  alias_method :_p, :__password

  # display reap version
  def __version ; version ; end
  alias_method :_v, :__version

  # option to display help
  def __help ; help ; end
  alias_method :_h, :__help

  # option to display tasks
  def __tasks; tasks ; end
  alias_method :_t, :__tasks

  #option for build version (only for package task)
  def _b ; $BUILD_VERSION = true ; end

  #def _f( pif ) ; $PROJECT_FILE = pif ; end
  #alias_method :_f, :__file

  # Commands

  # default action

  def default
    tasks
  end

  # display version

  def version
    puts "Reap  v#{Reap::Version}"
    exit 0
  end

  # display help

  def help(*args)
    unless args.empty?
      t = Reap.tasks[args[0]]
      s = "\n"
      s << "#{args[0]}: "
      s << t.task_desc.sub(/^\n+/, '').rstrip
      s << "\n\n"
      if thelp = t.task_help
        s << thelp.sub(/^\n+/, '').rstrip
      end
      s << "\n\n"
      puts s
    else
      puts HELP
    end
    exit 0
  end

  # list available tasks

  def tasks
    if Reap.projectfile?
      puts
      sorted_names = Reap.tasks.keys.sort
      margin = sorted_names.collect{ |n| n.size }.max + 6
      sorted_names.each do |name|
        task_class = Reap.tasks[name]
        puts "  #{name}".ljust(margin) + "#{task_class.task_desc}"
      end
      puts
    else
      puts "No project information file found."
    end
    exit 0
  end
  alias_method :ls, :tasks

  # copy the file from lib/data to the current dir.

  def template
    f = nil
    if ::ProjectInfo::INFO_FILES.any?{ |f| File.exists?(f) }
      puts "Project file '#{f}' already exists."
      return
    end
    filename = 'ProjectInfo'
    # if using gems
    if dir = Gem.gempath('reap')
      dir = File.join( dir, 'data', 'reap', 'scaffold', 'standard' )
    else
      dir = File.join( ::Config::CONFIG['datadir'], 'reap', 'scaffold', 'standard' )
    end
    f = File.join( dir, filename )
    raise "ProjectInfo template file #{f} is missing." unless File.file?( f )
    # copy
    FileUtils.install( f, '.' )
    puts "#{filename} created. You'll need to fill it out."
    exit 0
  end

  def scaffold( type=nil )
    content = Dir.entries('.') - [ '.', '..' ]
    if not content.empty? and not $FORCE
      puts "Directory already has content. Use -f option to force scaffolding."
      exit -1
    end
    case type
    when 'std', 'standard', nil
      type = 'standard'
    when 'svn', 'subversion'
      type = 'subversion'
    else
      puts "Unrecognized project type."
      exit -1
    end
    # need to add gems workaround
    if dir = Gem.gempath('reap')
      dir = File.join( dir, 'data', 'reap', 'scaffold', 'standard', type )
    else
      dir = File.join( ::Config::CONFIG['datadir'], 'reap', 'scaffold', type )
    end
    #FileUtils.mkdir_p( name )
    FileUtils.cp_r( File.join( dir, '.'), '.' )
    puts "Project ready."
  end

  # Add all the reap tasks.

  if Reap.register
    Reap.tasks.each do |sym,taskclass|
      define_method(sym) do |*args|
        taskclass.new(*args).execute
      end
    end
  end

end


HELP = <<-HERE

  reap v#{::Reap::Version}

  USAGE: reap [options...] <command> [arguments...]

  COMMANDS:

    tasks
      List all the current tasks with descriptions.
      This is the default action if no command
      is given. (Also aliased as 'ls'.)

    help [task]
      Displays this help information. If a task name
      is given, it will provide help information
      specific to that task.

    template
        Copies a ProjectInfo template into the current
        directory (if it does not already exist).

    scaffold [type]
        Builds a starter project in the current directory.
        There are two types: 'standard' and 'subversion'.
        These can be abbreviated 'std' and 'svn', repectively.
        If no type is given then standard is used.

  OPTIONS:

    -v --version
        Display the current version.

    -V --verbose
        Provides extra verbose processing information.

    -f --force
        Forces certain operations to be performed.

    -D --debug
        Provides extra verbose processing information.

    -f --file
        Specify alternate project file.

    -h --help
        Display this help information.

HERE