#!/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 "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, date.strftime("%b %d %H:%M(%Z)"), 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.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 ? normalize_path(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

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
