#!@{PERL_PATH} @{WFLAG}
#
# $Id: q,v 1.18 2001/01/11 21:35:11 jwise Exp $
#
# remy@ccs.neu.edu
# 27 June 1994
#
# Copyright (C) 1994 by Remy Evard
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# any later version.

#
# A copy of the license may be found in docs/license of the source
# distribution.
#
use strict;
no strict "vars";

push (@INC, "@{CODE_LIB_DIR}");

require "req-config.pl";
require "req-common.pl";

$use_dir = $active_dir;

$time=time();
$=   = 10000;

$no_low = 0;
$reverse = 0;
$do_merged = 0;
$prio_match = ".*";
$status_match = ".*";
$owner_match = "^.*\$";
$owner_changed = 0;
$user_match = ".*";
$see_all = 1;
$sort_by_time = 0;

$bottom = 0;     # lowest req number to print
$top = -1;       # highest req number to print (-1 means highest)
$offset = 0;     # number to print from first or last

&parse_args();

if($see_all == 0) {
  if(($user = (getpwuid($<))[0]) =~ /^\s*$/) {
    print STDERR "unable to get your login name";
    exit(1);
  }
  $user_match = "^$user\$";
  $^ = "statustop";
  $~ = "status";
  if(($top == $bottom) != 0) {
    &show($top);
    exit(0);
  }
}

if($sort_by_time) {
  @allfiles = &read_files($use_dir);
  %modified = &get_time_of_files($use_dir, @allfiles);
  @allfiles = (sort bytime @allfiles);
} else {
  @allfiles = (sort revnumerically &read_files($use_dir));
}

if(!$offset) {
  $top = time() if($top == -1);
  foreach $n (@allfiles) {
    push(@newlist, $n) if($n <= $top && $n >= $bottom);
  }
  @allfiles = @newlist;
}

@allfiles = reverse @allfiles if($reverse);
$count = 0;

file:
foreach $f (@allfiles) {
  last if($count && $count == $offset);

  &read_file("$use_dir/$f");

  $was_merged = $merged = 0;
  while($merged = &get_header("x-request-merged")) {
    if($do_merged) {
      $was_merged = $merged;
      $merged =~ s:\s*::g;
      &read_file("$use_dir/$merged");
    } else {
      next file;
    }
  }

  $own{$f}  = &get_header("x-request-owner");
  $req{$f}  = &get_header("x-request-user");
  $prio{$f} = &get_header("x-request-priority");
  $stat{$f} = $was_merged ? "> $was_merged" : &get_header("x-request-status");
  $sub{$f}  = &get_header("subject");
  $date{$f} = &get_header("x-request-date");
  $notified{$f} = &get_header("x-request-notified");

  if($req{$f} =~ /<(.*)>/) {
    $req{$f} = $1;
  } elsif ($req{$f} =~ /\((.*)\)>/) {
    $req{$f} = $1;
  }

  next if($no_low && $prio{$f} eq "low");
  next if($prio{$f} !~ /$prio_match/);
  next if($stat{$f} !~ /$status_match/);
  next if($own{$f} !~ /$owner_match/);
  next if($req{$f} !~ /$user_match/);

  ($subject{$f} = $sub{$f}) =~ s:@{PERL_TAGLINE_COMPARE}\s*::;

  if($no_low) {
	$priosym{$f} = " ";
  } else {
	$priosym{$f} = ($prio{$f} eq "low" ? "." : "o");
  }

  $priosym{$f} = "*" if($prio{$f} =~ /high/);
  
  $date{$f} = &date_diff(&getseconds(&get_header("x-request-date")), $time);
  $notified = &get_header("x-request-notified");
  if($notified =~ /^\s*$/) {
    $notified{$f} = "";
  } else {
    $not_sec = &getseconds($notified);
    $notified{$f} = &date_diff($not_sec, $time);
  }

  $count++;

  write;
}

if($see_all == 0) {
  print "--------------------------------------------------------------------------\n";
  print "Please mail all requests to \"@{MAILING_LIST_NAME}\", not to individuals.\n";
  print "Run `@{STATUS} <number>' the see the details of a specific request.\n";
}

exit(0);

# ===========================================================================
# Subs
# ===========================================================================

sub revnumerically {$b <=> $a;};

sub bytime {$modified{$a} <=> $modified{$b};};


sub get_time_of_files {
  local($dir, @allfiles) = @_;
  local($f, %modified);

  foreach $f (@allfiles) {
    $modified{$f} = -M "$dir/$f";
  }

  %modified;
}


sub date_diff {
  local($old, $new) = @_;
  local($diff, $minute, $hour, $day, $week, $month, $year, $s, $string);

  $diff = $new - $old;
  
  $minute = 60;
  $hour   = 60 * $minute;
  $day    = 24 * $hour;
  $week   = 7 * $day;
  $month  = 4 * $week;
  $year   = 356 * $day;
  
  if($diff < $minute) {
    $s=$diff;
    $string="sec";
  } elsif($diff < $hour) {
    $s = int($diff/$minute);
    $string="min";
  } elsif($diff < $day) {
    $s = int($diff/$hour);
    $string="hr";
  } elsif($diff < $week) {
    $s = int($diff/$day);
    $string="day";
  } elsif($diff < $month) {
    $s = int($diff/$week);
    $string="wk";
  } elsif($diff < $year) {
    $s = int($diff/$month);
    $string="mth";
  } else {
    $s = int($diff/$year);
    $string="yr";
  }
  return "$s $string";
} 

sub parse_args {
	while (defined ($_ = shift @ARGV))
  	{
		if (/-runbyuser/) {
			$see_all = 0;
			next;
		}
    		if (/:(\d+)/) {
    			$offset = $1;
    			next;
    		}
    		if (/(\d+):/) {
    			$offset = $1;
    			next;
    		}
    		if (/^(\d+)-(\d+)/) {
    			$bottom = $1;
      			$top = $2;
      			if($top < $bottom) {
				$temp = $top;
				$top = $bottom;
				$bottom = $temp;
			}
			next;
    		}
    		if (/^(\d+)-/) {
      			$bottom = $1;
      			next;
    		}
    		if (/^-(\d+)/) {
      			$top = $1;
      			next;
    		}
    		if (/^(\d+)/) {
      			$top = $bottom = $1;
      			$no_low = 0;
      			next;
    		}
    		if (/^-prio/) {
      			$prio_match = shift @ARGV;
      			if($prio_match eq "all") {
				$prio_match = ".*";
      			}
      			$no_low = 0;
      			next;
    		}
    		if (/^-op/) {
      			$status_match = "open";
      			next;
    		}
    		if (/^-ow/) {
			shift @ARGV;
      			if ((!defined($_)) || /^-/) {
				# put it back
				push @ARGV,$_;
        			if(($owner_match = (getpwuid($<))[0]) =~ /^\s*$/) {
          				die "unable to get your login name";
        			}
        			$owner_match = "^$owner_match\$";
      			} else {
        			$owner_match = $owner_changed ? "^$_\$|$owner_match" : "^$_\$" ;
        			$owner_changed = 1;
        			next;
      			}
    		}
    		if (/^-us/) {
			shift @ARGV;
      			$user_match = $_;
      			next;
    		}
    		if (/^-st/) {
			shift @ARGV;
      			$status_match = $_;
      			next;
    		}
    		if (/^-un/) {
      			$owner_match = $owner_changed ? "^\s*\$|$owner_match" : "^\\s*\$" ;
      			$owner_changed = 1;
      			next;
    		}
    		if (/^-res/) {
      			$use_dir = $resolved_dir;
      			next;
    		}
    		if (/^-r$/) {
      			$reverse = 1;
      			next;
    		}
    		if (/^-t$/) {
     	 		$sort_by_time = 1;
      			next;
    		}
    		if (/^-m/) {
			$do_merged = 1;
			$prio_match = ".*";
			$no_low = 0;
			next;
    		}
		else {
			&usage();
     			exit(0);
    		}
	}  
}

sub usage {
  print "usage: $0 <options>\n";
  print "       Where options are any of:\n";
  print "          -r               prints oldest requests first\n";
  print "          -t               prints most recently modified requests first\n";
  print "          -prio all        prints all of them regardless of priority\n";
  print "          -prio <prio>     prints all whose priority match <prio>\n";
  print "          -owner [<login>] prints all requests owned by <login>\n";
  print "          -user <login>    prints all requests made by <user>\n";
  print "          -open            prints only the open requests\n";
  print "          -status <status> prints only <status> requests\n";
  print "          -unowned         prints only the un-taken requests\n";
  print "          -resolved        prints the resolved requests\n";
  print "          <num>-<num>      print only requests in the number range\n";
  print "          <num>            print only request <num>\n";
  print "          :<num>           print a total of <num> requests\n";
  print "\n";
  print "       Without options, it prints all open requests.\n";
  print "\n";
}

sub show {
  local($show) = @_;

  ($active_file, $resolved_file) = &get_file_names($show);
  if(&active_request($active_file)) {
    &read_file($active_file);
    if(&get_header("x-request-user") eq $user) {
      open(FOO, $active_file) || die "Unable to open $active_file";
      while(<FOO>) {
        print;
      }
      close(FOO);
    } else {
      print "Request number $show is not available.\n";
    }
  } elsif(&resolved_request($resolved_file)) {
    &read_file($resolved_file);
    if(&get_header("x-request-user") eq $user) {
      open(FOO, $resolved_file) || die "Unable to open $resolved_file";
      while(<FOO>) {
        print;
      }
      close(FOO);
    } else {
      print "Request number $show is not available.\n";
    }
  } else {
    print "Request number $show is not available.\n";
  }
}  

sub get_file_names {
  # Given a request number, return the name of the associated active file
  # and resolved file.  
  # Don't do any checking for existence, but should probably make sure
  # the files are in reasonable places for security reasons.
  #
  local($num) = @_;
  ("$active_dir/$num", "$resolved_dir/$num");
}
  

sub resolved_request {
  local($file) = @_;
  (-f $file);
}


sub active_request {
  local($file) = @_;
  (-f $file);
}



format top =
Req # ! Own    Age      Told  Status  User     Subject
----- - ------ -------- ----- ------- -------- ---------------------------
.

format STDOUT =
@#### @ @<<<<< @>>>>>>> @>>>> @<<<<<< @<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<
$f, $priosym{$f}, $own{$f}, $date{$f}, $notified{$f}, $stat{$f}, $req{$f}, $subject{$f}
.

format statustop =
Req # ! Owner    Age     Status   Subject
----- - -------- ------- -------- ----------------------------------------
.

format status =
@#### @ @<<<<<<< @<<<<<< @<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$f, $priosym{$f}, $own{$f}, $date{$f}, $stat{$f}, $subject{$f}
.
