#!/usr/bin/perl -w
# vim:ts=2:sw=2:expandtab
#
# svn-graph.pl - produce a GraphViz .dot graph for the branch history
#                of a node
#
# ====================================================================
#    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.
# ====================================================================
#
# View graphs using a command like:
#
#   svn-graph.pl file:///tmp/repos | dotty -
#
# TODO:
#  - Calculate the repository root at runtime so the user can pass
#    the node of interest as a single URL.
#  - (Also?) produce the graphical output ourselves (SVG?) instead
#    of writing a GraphViz ".dot" data file.  This can be done with
#    GraphViz using 'dot'.
#  - Display svnmerge.py/Subversion merge history.
#

use strict;
use Getopt::Std;

# Turn off output buffering
$|=1;

require SVN::Core;
require SVN::Client;

# The URL of the Subversion repository we wish to graph
# (e.g. "http://svn.apache.org/repos/asf/subversion").
my $repos_url;

# The revision range we operate on, from $startrev -> $youngest.
my $youngest;
my $startrev;

# This is the node we're interested in
my $startpath;

# Set the variables declared above.
parse_commandline();

# The "interesting" nodes are potential sources for copies.  This list
#   grows as we move through time.
# The "tracking" nodes are the most recent revisions of paths we're
#   following as we move through time.  If we hit a delete of a path
#   we remove it from the tracking array (i.e. we're no longer interested
#   in it).
my %interesting = ("$startpath:$startrev", 1);
my %tracking = ("$startpath", $startrev);

my %codeline_changes_forward = ();
my %codeline_changes_back = ();
my %copysource = ();
my %copydest = ();

write_graph_descriptor();
#print STDERR "\n";



# Validate the command-line arguments, and set the global variables
# $repos_url, $youngest, $startrev, and $startpath.
sub parse_commandline
{
  my %cmd_opts;
  my $usage = "
usage: svn-graph.pl [-r START_REV:END_REV] [-p PATH] REPOS_URL

  -r the revision range (defaults to 0 through HEAD)
  -p the repository-relative path (defaults to /trunk)
  -h show this help information (other options will be ignored)
";

  # Defaults.
  $cmd_opts{'r'} = '1:HEAD';
  $cmd_opts{'p'} = '/trunk';

  getopts('r:p:h', \%cmd_opts) or die $usage;

  die $usage if scalar(@ARGV) < 1;
  $repos_url = SVN::Core::uri_canonicalize($ARGV[0]);

  $cmd_opts{'r'} =~ m/(\d+)(:(.+))?/;
  if ($3)
  {
    $youngest = ($3 eq 'HEAD' ? $3 : int($3));
    $startrev = int($1);
  }
  else
  {
    $youngest = ($3 eq 'HEAD' ? $1 : int($1));
    $startrev = 1;
  }

  $startpath = $cmd_opts{'p'};

  # Print help info (and exit nicely) if requested.
  if ($cmd_opts{'h'})
  {
    print($usage);
    exit 0;
  }
}

# This function is a callback which is invoked for every revision as
# we traverse change log messages.
sub process_revision
{
  my $changed_paths = shift;
  my $revision = shift || '';
  my $author = shift || '';
  my $date = shift || '';
  my $message = shift || '';
  my $pool = shift;

  #print STDERR "$revision\r";

  foreach my $path (keys %$changed_paths)
  {
    my $copyfrom_path = $$changed_paths{$path}->copyfrom_path;
    my $copyfrom_rev = undef;
    my $action = $$changed_paths{$path}->action;

    # See if we're deleting one of our tracking nodes
    if ($action eq 'D' and exists($tracking{$path}))
    {
      print "\t\"$path:$tracking{$path}\" ";
      print "[label=\"$path:$tracking{$path}\\nDeleted in r$revision\",color=red];\n";
      delete($tracking{$path});
      next;
    }

    ### TODO: Display a commit which was the result of a merge
    ### operation with [sytle=dashed,color=blue]

    # If this is a copy, work out if it was from somewhere interesting
    if (defined($copyfrom_path))
    {
      $copyfrom_rev = $tracking{$copyfrom_path};
    }
    if (defined($copyfrom_rev) &&
        exists($interesting{$copyfrom_path . ':' . $copyfrom_rev}))
    {
      $interesting{$path . ':' . $revision} = 1;
      $tracking{$path} = $revision;
      print "\t\"$copyfrom_path:$copyfrom_rev\" -> ";
      print " \"$path:$revision\"";
      print " [label=\"copy at r$revision\",color=green];\n";

      $copysource{"$copyfrom_path:$copyfrom_rev"} = 1;
      $copydest{"$path:$revision"} = 1;
    }

    # For each change, we'll walk up the path one component at a time,
    # updating any parents that we're tracking (i.e. a change to
    # /trunk/asdf/foo updates /trunk).  We mark that parent as
    # interesting (a potential source for copies), draw a link, and
    # update its tracking revision.
    do
    {
      if (exists($tracking{$path}) && $tracking{$path} != $revision)
      {
        $codeline_changes_forward{"$path:$tracking{$path}"} =
          "$path:$revision";
        $codeline_changes_back{"$path:$revision"} =
          "$path:$tracking{$path}";
        $interesting{$path . ':' . $revision} = 1;
        $tracking{$path} = $revision;
      }
      $path =~ s:/[^/]*$::;
    } until ($path eq '');
  }
}

# Write a descriptor for the graph in GraphViz .dot format to stdout.
sub write_graph_descriptor
{
  my $client = SVN::Client->new;
  # Begin writing the graph descriptor.
  print "digraph tree {\n";
  print "\tgraph [bgcolor=white];\n";
  print "\tnode [color=lightblue2, style=filled];\n";
  print "\tedge [color=black, labeljust=r];\n";
  print "\n";

  # Retrieve the requested history.
  $client->log($repos_url, $startrev, $youngest, 1, 0, \&process_revision);

  # Now ensure that everything is linked.
  foreach my $codeline_change (keys %codeline_changes_forward)
  {
    # If this node is not the first in its codeline chain, and it isn't
    # the source of a copy, it won't be the source of an edge
    if (exists($codeline_changes_back{$codeline_change}) &&
        !exists($copysource{$codeline_change}))
    {
      next;
    }

    # If this node is the first in its chain, or the source of
    # a copy, then we'll print it, and then find the next in
    # the chain that needs to be printed too
    if (!exists($codeline_changes_back{$codeline_change}) or
         exists($copysource{$codeline_change}) )
    {
      print "\t\"$codeline_change\" -> ";
      my $nextchange = $codeline_changes_forward{$codeline_change};
      my $changecount = 1;
      while (defined($nextchange))
      {
        if (exists($copysource{$nextchange}) or
            !exists($codeline_changes_forward{$nextchange}) )
        {
          print "\"$nextchange\" [label=\"$changecount change";
          if ($changecount > 1)
          {
            print 's';
          }
          print '"];';
          last;
        }
        $changecount++;
        $nextchange = $codeline_changes_forward{$nextchange};
      }
      print "\n";
    }
  }

  # Complete the descriptor (delaying write of font size to avoid
  # inheritance by any subgraphs).
  #my $title = "Family Tree\n$startpath, $startrev through $youngest";
  #print "\tgraph [label=\"$title\", fontsize=18];\n";
  print "}\n";
}
