#!/usr/bin/perl -w 
use warnings;

# Main program --------------------------------------------------------------------------------------
$pattern = "calendar\.htm";                                    # What are we looking for?
$here = ".";                                                   # What directory to start with?
$level = 0;                                                    # Traversal depth

traverse ($here);                                              # Walk the tree...
exit 0;                                                        # ...and we're done.

# Subroutines ---------------------------------------------------------------------------------------

# GETPAGE: read a file
sub getpage {

   my $filename = shift @_;             # File to read
   my $filetext = "";                   # Buffer for entire file

   # Read the file   
   open (IPAGE, "<$filename")           or die "PROBLEM: Unable to open file $filename ($!).\n";   
   {
      local $/;                         # Bypass line-by-line processing
      $filetext = <IPAGE>;              # Read the entire file in one go
      } 
   close (IPAGE);                       # No reason to keep it open any longer

   return $filetext; 
   }


# ANALYZE: look for the pattern within the page
sub analyze {

   my $filename = shift @_;             # File to examine
   my @matches = ();                    # Matches
   my $hitcount = 0;                    # Number of times pattern found in this file
   my $filetext = "";                   # Buffer for entire file

   # Grab the file  
   $filetext = getpage ($filename);   
   
   # Perform test
   if (@matches = $filetext =~ m{$pattern}mog)         
      {$hitcount = scalar (@matches);}                  
   
   return $hitcount;
   }

# TRAVERSE: breadth-first traversal of directory tree
sub traverse {
   
   my $dirname = shift @_;              # Directory to traverse
   my @targets = ();                    # Web pages
   my @subdirs = ();                    # Directories within this one
   my $linkhits = 0;                    # Number of matches in each file
   my $pagehits = 0;                    # Number of files with matches
   $level++;                            # Keep track of depth
   my $indent = "   " x $level;         # Indent report
   
   # Read the directory
   opendir (DIR, $dirname)              or die "PROBLEM: Unable to open directory $dirname ($!).\n";
   chdir ($dirname)                     or die "PROBLEM: Unable to change directory to $dirname.\n";
   my $pathname = `/bin/pwd`;
   print "$indent Level $level: Scanning directory $dirname ($pathname) ...\n";
   my @entries = sort readdir(DIR);

   # Process each entry
   ENTRY: foreach $entry (@entries) {
 
      # Ignore symlinks and other special files 
      next ENTRY if (-l $entry);	  
      next ENTRY unless (-f $entry || -d $entry);

      # Capture subdirectories (ignore . and ..)
      if ((-d $entry) && ($entry !~ /^\.{1,2}$/)) {
         push @subdirs, $entry;
         next ENTRY;
         }

      # Capture web pages
      elsif ($entry =~ /^(.*)\.[sS]?[hH][tT][mM][lL]?$/) { 
         push @targets, $entry; 
         next ENTRY;
         }
  
      # Ignore images, media, stylesheets, and so on
      else {
         next ENTRY;
         }

      }

   # Report on the files found at this level
   my $n_targets = scalar (@targets);   # Number of target pairs found
   my $n_subdirs = scalar (@subdirs);   # Number of subdirectories at this level
   print "$indent At this level: $n_targets web pages; $n_subdirs subdirectories.\n";  

   foreach $target (@targets) { 
      $linkhits = analyze ($target);
      if ($linkhits == 1) { 
         $pagehits++;
         print "   $indent $target : once.\n"; 
         }
      elsif ($linkhits > 1) {
         $pagehits++;
         print "   $indent $target : $linkhits occurrences.\n";       
         }
      }  
   if ($n_targets > 0) {
      print "   $indent Total pages containing pattern: $pagehits.\n";
      print "   $indent -----\n";
   }
	  
   # Now traverse the subdirectories recursively
   my $s_targets = 0;                   # Number of targets below this level
   my $s_subdirs = 0;                   # Number of subdirectories below this level
   foreach $subdir (@subdirs) {      
      ($t, $d) = traverse ($subdir);  
	  $s_targets += $t;
	  $s_subdirs += $d;
      }
	  
   # Calculate the cumulative counts
   $n_targets += $s_targets;
   $n_subdirs += $s_subdirs;   
   print "$indent Level $level: Total for $dirname and its $n_subdirs subdirectories: $n_targets web pages.\n";

   # Restore original directory
   chdir ("..")                         or warn "PROBLEM: Unable to restore directory.\n";

   $level--;     # undent
   
   # Report counts to next higher level incarnation
   return ($n_targets, $n_subdirs);
   }
