##############################################################################
# This program does "cleartool rmname -nco" (nocheckout)
#  for every version of the directory that holds the name
$G::usage = "$0 [-name <file/dir name> | -dbid <element-dbid>] -dir <directory element>";
##############################################################################

use strict;
use Config;

##############################################################################
# Put your guts of the progam in this sub
sub Main
##############################################################################
{
# Validate parameters
#
die "$G::usage\n" unless @ARGV == 4;
foreach $T::i ((0,2))
{
    if ($ARGV[$T::i] eq '-dir')
    {
        $G::dir  = ClearTool('describe -fmt "%En" "'.$ARGV[$T::i+1].'"');
        die "$G::usage\nNot a VOB directory.\n"
            unless ClearTool('describe -fmt "%m" "'.$G::dir.'"') eq "directory version";
        next;
    }
    if ($ARGV[$T::i] eq '-name')
    {
        $G::name = $ARGV[$T::i+1];
        die "$G::usage\nName contains invalid characters.\n" 
            if $G::name =~ /[\\\/\:\*\?\"\<\>\|]/;
        $G::i = 1; # index for name when splitting namespace entry
        next;
    }
    if ($ARGV[$T::i] eq '-dbid')
    {
        $G::dbid = $ARGV[$T::i+1];
        die "$G::usage\nDBID must be numeric.\n" 
            unless $G::dbid =~ /^\d+$/;
        $G::i = 0; # index for dbid when splitting namespace entry
        next;
    }
    die "$G::usage\n";
}
die "$G::usage\n" unless defined $G::dir;

# Verify we are not removing element from directory under which it was componentized.
#
@G::dump = ClearTool('dump "'.$G::dir.'@@"');
($G::dir_crde) = grep(/^crde=\d+/,@G::dump);
if ($G::dbid)
{
    @G::dump = ClearTool('dump dbid:'.$G::dbid);
}
else
{
    @G::dump = ClearTool('dump "'.$G::dir.($G::UNIX?"\/":"\\").$G::name.'@@"');
}
($G::elem_crde) = grep(/^crde=\d+/,@G::dump);
die "Error: This script cannot be used to remove element from an existing component ($G::elem_crde)\n"
   if $G::elem_crde ne "" and $G::elem_crde eq $G::dir_crde;

# Find all name entries
#
@T::vtree = ClearTool('lsvtree -all -short -obsolete "'.$G::dir.'"');
foreach $T::version (@T::vtree)
{
    if ($T::version =~ /[\\\/]CHECKEDOUT$/)
    {
        print "Warning: This script does not handle CHECKEDOUT versions\n";
        next if $T::vtree[-1] =~ /[\\\/]CHECKEDOUT\.\d+$/;
        push @T::vtree,ClearTool('lsco -fmt "%Xn.%Dn\n" -dir "'.$G::dir.'"');
        next;
    }
    elsif ($T::version !~ /[\\\/](CHECKEDOUT.)?\d+$/)
    {
        next; # skip branches
    }
    print "."; # progress indicator
    @T::dump = ClearTool('dump -long "'.$T::version.'"');
    $T::flag_dir_dump = 0;
    foreach $T::line (@T::dump)
    {
        last if $T::line eq "derived objects:";
        if ($T::line eq "directory entries:") {$T::flag_dir_dump = 1;}
        elsif ($T::flag_dir_dump)
        {
            @T::dir_entry = split(' ',$T::line,2);
            next unless $T::dir_entry[$G::i] eq ($G::i?$G::name:$G::dbid);
            $G::name_list{$T::version} = [@T::dir_entry];
            push (@T::dup_check,$T::dir_entry[$G::i-1]) if $T::dir_entry[$G::i-1] ne $T::dup_check[-1];
        }
    }
}
if ($G::dbid)
{
    die "\nNo versions found with entry for dbid $G::dbid\n"
        if @T::dup_check == 0;
    print "\nNOTE: Varying Names!"
        if @T::dup_check > 1;
}
else
{
    die "\nNo versions found with name entry \"$G::name\"\n"
        if @T::dup_check == 0;
    print "\nNOTE: Varying Element DBIDs!"
        if @T::dup_check > 1;
}


# Get explicit confirmation
#
if ($G::dbid)
{
    print "\nThe following entries were found for dbid $G::dbid\n";
    foreach $T::version (sort keys %G::name_list)
    {
        print '"'.$T::version.($G::UNIX?"\/":"\\").$G::name_list{$T::version}->[1].'"'."\n";
    }
}
else
{
    print "\nThe following entries were found with name \"$G::name\"\n";
    print "  Elem_dbid\tDirectory Version\n";
    foreach $T::version (sort keys %G::name_list)
    {
        printf ("%11d\t%s\n",$G::name_list{$T::version}->[0],$T::version);
    }
}
print "Continue and remove all the directory entries listed? [no] ";
chomp ($T::line = <STDIN>);
die "operation aborted\n" unless $T::line =~ /^y(es)?$/i;

# Remove the name entries
#
foreach $T::version (sort keys %G::name_list)
{
    ClearTool('rmname -nc -nco -force "'.$T::version.($G::UNIX?"\/":"\\").$G::name_list{$T::version}->[1].'"');
}

}
##############################################################################
sub ClearTool
##############################################################################
{
    return RunCmd($G::ct, @_);
}
##############################################################################
sub UCMUtil
##############################################################################
{
    return RunCmd($G::ucmutil, @_);
}
##############################################################################
sub RunCmd
##############################################################################
{
    my $cmd = join(' ', @_);
    printf("%s\n", $cmd) if ($G::cmd_echo);
    my $out = `$cmd`;
    $? and $G::cmd_die_on_error and die($out);
    printf(": %s\n", $out) if ($G::cmd_echo);

    if (wantarray()) {
        my @lines = split(/^/, $out);
        chomp(@lines);
        return @lines;
    } else {
        return $out;
   }
}
##############################################################################
sub Error # Print Error to screen
##############################################################################
{
    printf(@_);

    return 0;
}
##############################################################################
sub AtriaHome # Find Atria Home Dir
##############################################################################
{
    if (-d $ENV{ATRIAHOME}) {
        return $ENV{ATRIAHOME};
    } elsif ($G::UNIX) {
        return (-d '/usr/atria' ? '/usr/atria' : '/opt/rational/clearcase');
    } else {
        return ($ENV{'PATH'} =~ /(.*\;)?(.\:\\.*\\ClearCase)\\bin(;.*)/ ? $2 : 'C:\\Program Files\\Rational\\ClearCase');
    }
}

##############################################################################
# Find Unix or Windows Atria Home Dir
##############################################################################
$G::UNIX = ($Config::Config{osname} ne 'MSWin32');
if ($G::UNIX) {
    $G::ct       = AtriaHome() . '/bin/cleartool';
    $G::ucmutil = AtriaHome() . '/etc/utils/ucmutil';
} else {
    $G::ct       = "\"" . AtriaHome() . '\\bin\\cleartool'       . "\"";
    $G::ucmutil = "\"" . AtriaHome() . '\\etc\\utils\\ucmutil' . "\"";
}
$G::cmd_echo = 0;
$G::cmd_die_on_error = 0;
###############################################################################
# This pretends to void(main);
###############################################################################
Main() || exit(1);
exit(0);

