#!/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.
#
######################################################################
#    Licensed to the Apache Software Foundation (ASF) under one
#    or more contributor license agreements.  See the NOTICE file
#    distributed with this work for additional information
#    regarding copyright ownership.  The ASF licenses this file
#    to you under the Apache License, Version 2.0 (the
#    "License"); you may not use this file except in compliance
#    with the License.  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing,
#    software distributed under the License is distributed on an
#    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
#    KIND, either express or implied.  See the License for the
#    specific language governing permissions and limitations
#    under the License.
######################################################################
#

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 subcommand: #{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
