#
# futils.rb
#
#   Copyright (c) 1999,2000 Minero Aoki <aamine@dp.u-netsurf.ne.jp>
#
#   This program is free software.
#   You can distribute/modify this program under the terms of
#   the GNU General Public License version 2 or later.
#

require 'amstd/fileutils'


module FileUtils

  include FileTest
  extend FileTest


  module_function


  @verbose = false
  @futils_output = $stderr

  def futilsmsg( msg )
    @futils_output ||= $stderr
    @futils_output.puts 'futils: ' + msg
  end
  private_class_method :futilsmsg


  FU = FILEUTILS

  def cd( dn, &block )
    FU.cd( dn, &block )
  end
  alias chdir cd

  def indir( dir, *args )
    args.flatten!
    args.collect do |fn|
      fn[0,1] == '/' ? fn : FU.join(dir, fn)
    end
  end

  def isdir( *args )
    args.flatten!
    dn = FU.join( *args )
    mkdir_p dn
    dn
  end

  def mustdir( dn )
    full = File.expand_path( dn )
    unless directory? full then
      raise ArgumentError, "#{dn} is not directory"
    end
    full
  end

  def pwd
    Dir.pwd
  end


  def expand( fn )
    File.expand_path fn
  end

  def dirname( fn )
    File.dirname fn
  end

  def basename( fn )
    File.basename fn
  end

  def fjoin( *args )
    args.flatten!
    args.join('/')
  end
  alias sepjoin fjoin

  def is_newer?( new, *old )
    old.flatten!
    old.each do |fn|
      return false unless FU.is_newer? new, fn
    end
    true
  end
  alias uptodate? is_newer?

  def is_older?( old, *new )
    new.flatten!
    new.each do |fn|
      return false unless FU.is_older? old, fn
    end
    true
  end


  def mkdir( *args )
    args.flatten!
    futilsmsg "mkdir #{args.join ' '}" if @verbose
    args.each do |i|
      Dir.mkdir File.expand_path(i)
    end
  end

  def mkdir_p( *args )
    args.flatten!
    futilsmsg "mkdir -p #{args.join ' '}" if @verbose
    args.each do |i|
      FU.mkdir_p File.expand_path(i)
    end
  end
  alias mkpath mkdir_p

  def rmdir( *args )
    args.flatten!
    futilsmsg "rmdir -p #{args.join ' '}" if @verbose
    args.each do |i|
      Dir.rmdir File.expand_path(i)
    end
  end


  def ln( old, new )
    futilsmsg "ln #{old} #{new}" if @verbose
    FU.ln File.expand_path(old), File.expand_path(new)
  end

  def ln_s( old, new )
    futilsmsg "ln -s #{old} #{new}" if @verbose
    FU.ln_s File.expand_path(old), File.expand_path(new)
  end


  BSIZE = FU::BSIZE

  def cp( *args )
    args.flatten!
    to = args.pop
    futilsmsg "cp #{args.join ' '} #{to}" if @verbose
    to = File.expand_path( to )
    args.each do |i|
      FU.cp File.expand_path(i), to
    end
  end

  def cp_r( from, to )
    futilsmsg "cp -r #{from} #{to}" if @verbose
    FU.cp_r File.expand_path(from), File.expand_path(to)
  end


  def mv( *args )
    args.flatten!
    to = args.pop
    futilsmsg "mv #{args.join ' '} #{to}" if @verbose
    to = File.expand_path( to )
    args.each do |i|
      FU.mv File.expand_path(i), to
    end
  end


  def rm( *args )
    args.flatten!
    futilsmsg "rm #{args.join ' '}" if @verbose
    args.each do |i|
      FU.rm File.expand_path(i)
    end
  end

  def rm_f( *args )
    args.flatten!
    futilsmsg "rm -f #{args.join ' '}" if @verbose
    args.each do |i|
      FU.rm_f File.expand_path(i)
    end
  end

  def rm_rf( *args )
    args.flatten!
    futilsmsg "rm -rf #{args.join ' '}" if @verbose
    args.each do |i|
      FU.rm_rf File.expand_path(i)
    end
  end


  def cmp( a, b )
    futilsmsg "cmp #{a} #{b}" if @verbose
    FU.cmp a, b
  end
  alias identical? cmp


  def install( from, to, mode = nil )
    futilsmsg "install #{mode ? '%o ' % mode : ''}#{from} #{to}" if @verbose
    FU.install from, to, mode
  end

  def install_str( fname, upd )
    str = nil
    if File.file? fname then
      File.open( fname ) {|f| str = f.read }
    end
    if not str or str != upd then
      File.open( fname, 'w' ) do |f|
        f.write upd
      end
    end
  end


  def foreach_fullpath( dn )
    d = Dir.open( dn )
    dirs = d.to_a
    d.close
    dirs.each do |fn|
      next if fn == '.' or fn == '..'
      yield FU.join(dn, fn)
    end
  end

  def chmod( mode, *args )
    args.flatten!
    futilsmsg sprintf('chmod %o %s', mode, args.join(' ')) if @verbose
    File.chmod mode, *args
  end

  Separator = FU::Separator


  def command( line )
    futilsmsg line if @verbose
    unless ret = system( line ) then
      raise ArgumentError, "'system #{line}' failed"
    end
    ret
  end

end
