#!/usr/bin/env ruby
#
# svnshell.rb : a Ruby-based shell interface for cruising 'round in
#               the filesystem.
#
# Usage: ruby svnshell.rb REPOS_PATH, where REPOS_PATH is a path to
# a repository on your local filesystem.
#
# NOTE: This program requires the Ruby readline extension.
# See http://wiki.rubyonrails.com/rails/show/ReadlineLibrary
# for details on how to install readline for Ruby.
#
######################################################################
#
# Copyright (c) 2000-2005 CollabNet.  All rights reserved.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution.  The terms
# are also available at http://subversion.tigris.org/license-1.html.
# If newer versions of this license are posted there, you may use a
# newer version instead, at your option.
#
######################################################################
#

require "readline"
require "shellwords"
require "time"

require "svn/fs"
require "svn/core"
require "svn/repos"

# SvnShell: a Ruby-based shell interface for cruising 'round in
#           the filesystem.
class SvnShell

  # A list of potential commands. This list is populated by 
  # the 'method_added' function (see below).
  WORDS = []

  # Check for methods that start with "do_" 
  # and list them as potential commands
  class << self
    def method_added(name)
      if /^do_(.*)$/ =~ name.to_s
        WORDS << $1
      end
    end
  end
  
  # Constructor for SvnShell
  #
  # path: The path to a Subversion repository
  def initialize(path)
    @repos_path = path
    @path = "/"
    self.rev = youngest_rev
    @exited = false
  end

  # Run the shell
  def run

    # While the user hasn't typed 'exit' and there is still input to be read
    while !@exited and buf = Readline.readline(prompt, true)

      # Parse the command line into a single command and arguments
      cmd, *args = Shellwords.shellwords(buf)

      # Skip empty lines
      next if /\A\s*\z/ =~ cmd.to_s

      # Open a new connection to the repo
      @fs = Svn::Repos.open(@repos_path).fs
      setup_root

      # Execute the specified command
      dispatch(cmd, *args)

      # Find a path that exists in the current revision
      @path = find_available_path

      # Close the connection to the repo
      @root.close

    end
  end

  # Private functions
  private

  # Get the current prompt string
  def prompt

    # Gather data for the prompt string
    if rev_mode?
      mode = "rev"
      info = @rev
    else
      mode = "txn"
      info = @txn
    end

    # Return the prompt string
    "<#{mode}: #{info} #{@path}>$ "
  end
  
  # Dispatch a command to the appropriate do_* subroutine
  def dispatch(cmd, *args)

    # Dispatch cmd to the appropriate do_* function
    if respond_to?("do_#{cmd}", true)
      begin
        __send__("do_#{cmd}", *args)
      rescue ArgumentError
        # puts $!.message
        # puts $@
        puts("Invalid argument for #{cmd}: #{args.join(' ')}")
      end
    else
      puts("Unknown command: #{cmd}")
      puts("Try one of these commands: ", WORDS.sort.join(" "))
    end
  end

  # Output the contents of a file from the repository
  def do_cat(path)

    # Normalize the path to an absolute path
    normalized_path = normalize_path(path)

    # Check what type of node exists at the specified path
    case @root.check_path(normalized_path)
    when Svn::Core::NODE_NONE
      puts "Path '#{normalized_path}' does not exist."
    when Svn::Core::NODE_DIR
      puts "Path '#{normalized_path}' is not a file."
    else
      # Output the file to standard out
      @root.file_contents(normalized_path) do |stream|
        puts stream.read(@root.file_length(normalized_path))
      end
    end
  end

  # Set the current directory
  def do_cd(path="/")

    # Normalize the path to an absolute path
    normalized_path = normalize_path(path)

    # If it's a valid directory, then set the directory
    if @root.check_path(normalized_path) == Svn::Core::NODE_DIR
      @path = normalized_path
    else
      puts "Path '#{normalized_path}' is not a valid filesystem directory."
    end
  end
  
  # List the contents of the current directory or provided paths
  def do_ls(*paths)

    # Default to listing the contents of the current directory
    paths << @path if paths.empty?
    
    # Foreach path
    paths.each do |path|

      # Normalize the path to an absolute path
      normalized_path = normalize_path(path)
      
      # Is it a directory or file?
      case @root.check_path(normalized_path)
      when Svn::Core::NODE_DIR

        # Output the contents of the directory
        parent = normalized_path
        entries = @root.dir_entries(parent)

      when Svn::Core::NODE_FILE

        # Split the path into directory and filename components
        parts = path_to_parts(normalized_path)
        name = parts.pop
        parent = parts_to_path(parts)

        # Output the filename
        puts "#{parent}:#{name}"

        # Double check that the file exists
        # inside the parent directory
        parent_entries = @root.dir_entries(parent)
        if parent_entries[name].nil?
          # Hmm. We found the file, but it doesn't exist inside
          # the parent directory. That's a bit unusual.
          puts "No directory entry found for '#{normalized_path}'"
          next
        else
          # Save the path so it can be output in detail
          entries = {name => parent_entries[name]}
        end
      else
        # Path is not a directory or a file,
        # so it must not exist
        puts "Path '#{normalized_path}' not found."
        next
      end

      # Output a detailed listing of the files we found
      puts "   REV   AUTHOR  NODE-REV-ID     SIZE              DATE NAME"
      puts "-" * 76

      # For each entry we found...
      entries.keys.sort.each do |entry|

        # Calculate the full path to the directory entry
        fullpath = parent + '/' + entry
        if @root.dir?(fullpath)
          # If it's a directory, output an extra slash
          size = ''
          name = entry + '/'
        else
          # If it's a file, output the size of the file
          size = @root.file_length(fullpath).to_i.to_s
          name = entry
        end
        
        # Output the entry
        node_id = entries[entry].id.to_s
        created_rev = @root.node_created_rev(fullpath)
        author = @fs.prop(Svn::Core::PROP_REVISION_AUTHOR, created_rev).to_s
        date = @fs.prop(Svn::Core::PROP_REVISION_DATE, created_rev)
        args = [
          created_rev, author[0,8],
          node_id, size, format_date(date), name
        ]
        puts "%6s %8s <%10s> %8s %17s %s" % args
        
      end
    end
  end

  # List all currently open transactions available for browsing
  def do_lstxns
    
    # Get a sorted list of open transactions
    txns = @fs.list_transactions
    txns.sort
    counter = 0
    
    # Output the open transactions
    txns.each do |txn|
      counter = counter + 1
      puts "%8s  " % txn
      
      # Every six transactions, output an extra newline
      if counter == 6
        puts
        counter = 0
      end
    end
    puts
  end
  
  # Output the properties of a particular path
  def do_pcat(path=nil)
    
    # Default to the current directory
    catpath = path || @path

    # Make sure that the specified path exists
    if @root.check_path(catpath) == Svn::Core::NODE_NONE
      puts "Path '#{catpath}' does not exist."
      return
    end

    # Get the list of properties
    plist = @root.node_proplist(catpath)
    return if plist.nil?

    # Output each property 
    plist.each do |key, value|
      puts "K #{key.size}"
      puts key
      puts "P #{value.size}"
      puts value
    end

    # That's all folks!
    puts 'PROPS-END'
    
  end
      
  # Set the current revision to view
  def do_setrev(rev)
    
    # Make sure the specified revision exists
    begin
      @fs.root(Integer(rev)).close
    rescue Svn::Error
      puts "Error setting the revision to '#{rev}': #{$!.message}"
      return
    end
    
    # Set the revision
    self.rev = Integer(rev)
    
  end
  
  # Open an existing transaction to view
  def do_settxn(name)

    # Make sure the specified transaction exists
    begin
      txn = @fs.open_txn(name)
      txn.root.close
    rescue Svn::Error
      puts "Error setting the transaction to '#{name}': #{$!.message}"
      return
    end
    
    # Set the transaction
    self.txn = name
    
  end

  # List the youngest revision available for browsing
  def do_youngest
    rev = @fs.youngest_rev
    puts rev
  end
  
  # Exit this program
  def do_exit
    @exited = true
  end

  # Find the youngest revision
  def youngest_rev
    Svn::Repos.open(@repos_path).fs.youngest_rev
  end

  # Set the current revision
  def rev=(new_value)
    @rev = new_value
    @txn = nil
    reset_root
  end

  # Set the current transaction
  def txn=(new_value)
    @txn = new_value
    reset_root
  end

  # Check whether we are in 'revision-mode'
  def rev_mode?
    @txn.nil?
  end
  
  # Close the current root and setup a new one
  def reset_root
    if @root
      @root.close
      setup_root
    end
  end

  # Setup a new root
  def setup_root
    if rev_mode?
      @root = @fs.root(@rev)
    else
      @root = @fs.open_txn(name).root
    end
  end
  
  # Convert a path into its component parts
  def path_to_parts(path)
    path.split(/\/+/)
  end

  # Join the component parts of a path into a string
  def parts_to_path(parts)
    normalized_parts = parts.reject{|part| part.empty?}
    "/#{normalized_parts.join('/')}"
  end
  
  # Convert a path to a normalized, absolute path
  def normalize_path(path)

    # Convert the path to an absolute path
    if path[0,1] != "/" and @path != "/"
      path = "#{@path}/#{path}"
    end

    # Split the path into its component parts
    parts = path_to_parts(path)
    
    # Build a list of the normalized parts of the path 
    normalized_parts = []
    parts.each do |part|
      case part
      when "."
        # ignore
      when ".."
        normalized_parts.pop
      else
        normalized_parts << part
      end
    end

    # Join the normalized parts together into a string
    parts_to_path(normalized_parts)

  end

  # Find the parent directory of a specified path
  def parent_dir(path)
    normalize_path("#{path}/..")
  end
  
  # Try to land on the specified path as a directory.
  # If the specified path does not exist, look for 
  # an ancestor path that does exist.
  def find_available_path(path=@path)
    if @root.check_path(path) == Svn::Core::NODE_DIR
      path
    else
      find_available_path(parent_dir(path))
    end
  end

  # Format a date for output in a standard format
  def format_date(date_str)
    date = Svn::Util.string_to_time(date_str)
    date.strftime("%b %d %H:%M(%Z)")
  end
  
end


# Autocomplete commands
Readline.completion_proc = Proc.new do |word|
  SvnShell::WORDS.grep(/^#{Regexp.quote(word)}/)
end

# Output usage information if necessary
if ARGV.size != 1
  puts "Usage: #{$0} REPOS_PATH"
  exit(1)
end

# Create a new SvnShell with the command-line arguments and run it
SvnShell.new(ARGV.shift).run
