#!perl -w
######################
######################

#use strict;
use Cwd;
use File::Basename;
use File::Path;


sub needsFiltering();
sub cleanDirectory($);
sub filter($$@);
sub mycopy($@);
sub preprocess();

my $target =0;
my $Cmd = basename($0);
my $usage = <<ENDUSAGE;
Usage: $Cmd [userdoc|devdoc|all]
    Generate component documentation with doxygen 
ENDUSAGE

# Make sure there is one argument
   if ($#ARGV != 0) 
   {
      print $usage;
      exit;
   }

   my @buffer =();

   $target=$ARGV[0];
   if (($target ne "devdoc")  && 
       ($target ne "userdoc") && 
       ($target ne "all"))
   {
      print $usage;
      exit;      
	}

   # Do we need to pre-process files ?
   if (needsFiltering())
   {
      print "Preprocessing\n";
      preprocess();
	}
   # Let's call make: twice, as the behaviour is not the same
   if (($target eq "userdoc") || ($target eq "all"))
   {
      `make userdoc`;
	};

   if (($target eq "devdoc") || ($target eq "all"))
   {
      `make devdoc`;
	};

# This routine determines if files need to be filtered (_SDE_FILTERDOX)
# Returns value: 0 if filtering is not needed, <> 0 otherwise
sub needsFiltering()
{
   my $result=0;
   # Retrieve the information from the SDE variable _SDE_FILTERDOX
   @buffer=`make var=_SDE_FILTERDOX _sde_print_var`;
   foreach $_ (@buffer)
   {
   # Process lines from the start, looking for _SDE_FILTERDOX
      if (/^_SDE_FILTERDOX=/)
	   {
        $result=$';
	   }
   }
   chomp($result);
   return (length($result))
}

# This routine cleans a directory content (delete if exists + create)
# Argument: dirctory to clean
sub cleanDirectory($)
{
   $mydir=$_[0];
   if (-d $mydir)
	{
      rmtree ($mydir);
	}
   mkpath ($mydir);
}

# This routine actually calls a filter script with input files
# Output is redirected to specified directory
# Arguments are output dir, filter, files to filter
sub filter($$@)
{
   ($outdir,$filter,@filesList)=@_;
   foreach $_ (@filesList)
   {
   # Process each file
      $command="perl ".$filter." ".$_." > ".$outdir."/".basename($_);
      `$command`;
   }
}

# This routine actually copies input files in the output directories
# It is used when some files do not need to be filtered.
# Arguments are output dir, files to copy
sub mycopy($@)
{
   ($outdir,@filesList)=@_;
   foreach $_ (@filesList)
   {
   # Process each file
      $command="cp ".$_." ".$outdir;
      `$command`;
   }
}

# This routine checks the availability of the preprocessing filter
# Returns the full name of the filter
sub checkFilter()
{
   my $temp      =0;
   my $doxyFilter=0;

   $doxyFilter=$ENV{_TMROOT}."/project/sites/$ENV{_TMSITE}/doxygenfilter.pl";
   if (-r $doxyFilter)
	{
      return ($doxyFilter)
   }
   else
	{
      my $filterError = <<ENDFILTERERROR;
Error: file $doxyFilter does not exist or is not readable.
ENDFILTERERROR
      print  $filterError;
      exit
	}
}


# This routine filters the input files (result is tagged files)
# Needs to be called only if files need preprocessing
sub preprocess()
{
   my @filesToProcess=();
   my @headerfiles   =();
   my $outdir        =0;
   my $filter        =checkFilter();

   if (($target eq "userdoc") || ($target eq "all"))
   {
      # At first, clean the directories
      @buffer=`make var=_SDE_AUTODOCOUTUSR_DIR _sde_print_var`;
      foreach $_ (@buffer)
      {
      # Process lines from the start, looking for _SDE_AUTODOCOUTUSR_DIR
         if (/^_SDE_AUTODOCOUTUSR_DIR=/)
	      {
            $outdir=$';
	      }
      }
      chomp($outdir);
      $outdir=$outdir."/prep";
      cleanDirectory($outdir);
      # Now, really preprocess the files to feed doygen with them
      @filesToProcess=getHeaderFilesList();
      filter($outdir,$filter,@filesToProcess);
	}
   if (($target eq "devdoc") || ($target eq "all"))
   {
      @buffer=`make var=_SDE_AUTODOCOUTDEV_DIR _sde_print_var`;
      foreach $_ (@buffer)
      {
      # Process lines from the start, looking for _SDE_AUTODOCOUTDEV_DIR
         if (/^_SDE_AUTODOCOUTDEV_DIR=/)
	      {
            $outdir=$';
	      }
      }
      chomp($outdir);
      $outdir=$outdir."/prep";
      cleanDirectory($outdir);
      # Now, really preprocess the files to feed doygen with them
      # At this stage, only header files. Sources will only be copied
      # The filter does not handle them very properly
      @filesToProcess=getHeaderFilesList();
      filter($outdir,$filter,@filesToProcess);
      @filesToProcess=getCSourceFilesList();
      @filesToProcess=(@filesToProcess,getCPPSourceFilesList());
      @filesToProcess=(@filesToProcess,getASMSourceFilesList());
#      filter($outdir,$filter,@filesToProcess);
      mycopy($outdir,@filesToProcess);
	}


   # Create the directory for preprocessing
}

# Get the list of C source files using C_SOURCES SDE variable
sub getCSourceFilesList
{
   my $workdir=0;
   my @csources=();
   my $sourceslist=0;

# Retrieve the current directory
   $workdir=cwd();

# Get the list of the C source files required
   @buffer=`make var=C_SOURCES _sde_print_var`;

   foreach $_ (@buffer)
   {
   # Process lines from the start, looking for C_SOURCES=...
      if (/^C_SOURCES=/)
	   {
        $sourceslist=$';
	   }
   }
   # Get all the C source files (absolute path)
   chomp ($sourceslist);
   if (length($sourceslist)>0)
   {
      # Get all the cpp source files (absolute path)
      @csources = split(/ /,$sourceslist);
      for(my $i=0;$i<=$#csources;$i++)
      {
         $csources[$i]=$workdir.'/'.$csources[$i];
      }
	}
   return @csources
}

# Get the list of CPP source files using CPP_SOURCES SDE variable
sub getCPPSourceFilesList
{
   my $workdir=0;
   my @cppsources=();
   my $sourceslist=0;

# Retrieve the current directory
   $workdir=cwd();

# Get the list of the CPP source files required
   @buffer=`make var=CXX_SOURCES _sde_print_var`;

   foreach $_ (@buffer)
   {
   # Process lines from the start, looking for CXX_SOURCES=...
      if (/^CXX_SOURCES=/)
	   {
        $sourceslist=$';
	   }
   }
   chomp ($sourceslist);
   if (length($sourceslist)>0)
   {
      # Get all the cpp source files (absolute path)
      @cppsources = split(/ /,$sourceslist);
      for(my $i=0;$i<=$#cppsources;$i++)
      {
         $cppsources[$i]=$workdir.'/'.$cppsources[$i];
      }
	}
   return @cppsources
}

# Get the list of assembler source files using S_SOURCES SDE variable
sub getASMSourceFilesList
{
   my $workdir=0;
   my @asmsources=();
   my $sourceslist=0;

# Retrieve the current directory
   $workdir=cwd();

# Get the list of the S source files required
   @buffer=`make var=S_SOURCES _sde_print_var`;

   foreach $_ (@buffer)
   {
   # Process lines from the start, looking for C_SOURCES=...
      if (/^S_SOURCES=/)
	   {
        $sourceslist=$';
	   }
   }
   chomp ($sourceslist);
   if (length($sourceslist)>0)
   {
      # Get all the assembler source files (absolute path)
      @asmsources = split(/ /,$sourceslist);
      for(my $i=0;$i<=$#asmsources;$i++)
      {
         $asmsources[$i]=$workdir.'/'.$asmsources[$i];
      }
	}
   return @asmsources
}

# Get the list of header files using $_TMROOT/DIR_LOCAL SDE variables
sub getHeaderFilesList
{
   #Retrieve the _TMROOT from SDE
   my $workdir=$ENV{_TMROOT};

   #Retrieve the DIR_LOCAL from gmake
   @buffer=`make var=DIR_LOCAL _sde_print_var`;
   foreach $_ (@buffer)
   {
   # Process lines from the start, looking for DIR_LOCAL=...
      if (/^DIR_LOCAL=/)
	   {
        $workdir=$workdir.'/'.$';
	   }
   }
   chomp $workdir;

   #Append the include directory
   $workdir=$workdir.'/inc';
   # Retrieve the header files
   @headerfiles=<$workdir/*.h>;
   return @headerfiles;
}        

