#! perl -w

=head1 NAME

cfx5post - run CFX-Post

=cut

#!/bin/sh
#==============================================================================
# @(#) $Id$
#-------------------------------------------------------------------------------
##
#H Name:
##
## cfx5post
##
#H Purpose:
##
## Run the CFX Post Processor
##
#H Synopsis:
##
## cfx5post [-gui|-line|-batch <file>|-monitor <directory>]
##         [-report <option> [-outdir <dir>] [-name <name>]]
##         [-graphics ogl|mesa] [-state <statefile>] [-session <sessionfile>]
##         [-display <display>] [-multiconfig single|separate|last] [-help] [-v]
##
## []  denotes an optional argument.
## |   separates mutually exclusive arguments.
## ... following an argument indicates that it may be repeated.
## <>  denotes that substitution of a suitable value is required. All other
##     arguments are keywords, some of which have a short form.
##
#H Arguments:
##
#A -batch <file>
##     Starts CFD-Post in batch mode, with session file <file>.  The
##     session file is played, and then CFD-Post exits.
##
#A -report <option>
##     Starts CFD-Post in report generation mode.  <option> can be either a
##     state/session file, auto, minimal, or a predefined template name.
##
#A -outdir <dir>
##     directory in which to produce report
##
#A -name <name>
##     name of report
##
#A -display <display>
#A -d <display>
##     Display the graphical user interface on the X11 server <display>
##     instead of using the X11 server defined by the DISPLAY environment
##     variable.
##
#A -graphics ogl|mesa
#A -gr ogl|mesa
##     Set the graphics mode to use for the GUI to the OpenGL (hardware)
##     or MESA (software)-based version.
##
#A -gui
##     Starts CFD-Post in GUI mode.  This is the default.
##
#A -help
#A -h
##     Print this message.
##
#A -line
##     Starts CFD-Post in line mode.
##
#A -monitor <directory>
##     Starts CFD-Post in monitoring mode by automatically attaching to the run 
##     in progress in <directory>. Note: CFD-Post can only monitor runs that have 
##     been defined using Monitor Surfaces.
##
#A -multiconfig single|separate|last
#A -m single|separate|last
##     Specifies the load option for multi-configuration files.
##
#A -results <file>
#A -res <file>
##     Loads the given results file after starting CFD-Post.
##
#A -session <file>
#A -s <file>
#A -play <file>
##     Plays the named session file after starting.
##
#A -state <file>
#A -t <file>
##     Loads the named state file after starting.
##
#A -verbose
#A -v
##     Specifying this option may result in additional output being sent to 
##     the UNIX standard output file (normally the screen).
##
#U ****************************************************************************
#U *                                                                          *
#U *     The following features are supported only within CFX and are not     *
#U *     shown by the -help option when the command is run elsewhere.         *
#U *                                                                          *
#U ****************************************************************************
#U
#U -local
#U     Rather than using the central version of CFD-Post, assume that
#U     the current directory is the root of a locally-built version
#U     and run from that.
#U
#U -local-root <dir>
#U     Rather than using the central version of CFD-Post, assume that
#U     the specified directory <dir> is the root of a locally-built
#U     version and run from that.
#U
#U -post
#U     Temporary switch to run CFD-Post rather than CFX-Pre.
#U
#U -run-with <cmd>
#U     Rather than running directly, uses <cmd> as a wrapper to invoke it.
#U
#U -wid <id>
#U     Sets the window ID in which to embed the CFX-Pre window
#U
#U -control-port <id>
#U     Sets the port number to which CFD-Post will communicate (i.e. WB)
#U
#U -nogui
#U     Specifies whether to run the app with the GUI or without - usually
#U     used when running under WB.

#
# before we do anything else which might use it, restore TMPDIR if it
# was changed by cfx5build.
#
if (exists $ENV{CFX_BUILD_ORIG_TMPDIR}) {
  if ($ENV{CFX_BUILD_ORIG_TMPDIR} eq "TMPDIR was not set") {
    delete $ENV{TMPDIR};
  } else {
    $ENV{TMPDIR}=$ENV{CFX_BUILD_ORIG_TMPDIR};
  }
  delete $ENV{CFX_BUILD_ORIG_TMPDIR};
}

# get the standard CFX-5 library directory
BEGIN {
  if ($0 =~ m!^([a-z]:)?[\\/]!i) {
    # it's an absolute path, use it as-is
    (my $nd=$0) =~ s!(perllib[\\/])?[^\\/]*$!!i;
    unshift @INC, "$nd/perllib";
  } else {
    # wrap this in an eval, and if it fails, pray ... for example,
    # this can fail on Windows if we're running off a share.
    eval {
      require FindBin;
      FindBin->import();
      unshift @INC, "$FindBin::Bin/perllib";
      my $dummy=$FindBin::Bin; # kill used only once warning
    };
    warn $@ if $@;
  }
  if (defined $ENV{CFX_LOCAL_PERLLIB}) {
     unshift @INC, $ENV{CFX_LOCAL_PERLLIB};
  }

}

#
# Generate an unique session ID for the ANSYS help system.
#
if(! $ENV{ANSHELP_SESSION_ID})
{
	srand (time ^ $$ ^ unpack "%L*", rand());
	my $ANSHELP_SESSION_ID = "";
	for ($i = 1; $i <= 64; $i++)
	{
		$ANSHELP_SESSION_ID = $ANSHELP_SESSION_ID . sprintf("%x", int(rand(16)));
	}
	$ENV{ANSHELP_SESSION_ID} = $ANSHELP_SESSION_ID;
}

use CFX5::Init;
CFX5::Init::init();

use vars qw($CVSVersion);
sub BEGIN {
  $CVSVersion='@(#) $Id$\n';
}

use strict;

use CFX5::Output qw(:all);
use CFX5::Config qw(%Config export_conf append_to_libpath prepend_to_libpath append_to_execpath prepend_to_execpath setconf check_gui_support);
use CFX5::PrintConfig;

use CFX5::CmdLine qw(:util parse_cmdline);

use CFX5::Help;

use CFX5::PathManip qw(join_file split_file fullpath basename dirname);
use CFX5::FileTests;
#use CFX5::FileOps qw(link_files copy_file_for_read move_file move_file_to_backup glob_suffix create_empty_file);
#use File::Path qw(rmtree);

use CFX5::ExitRoutines qw(:tidyup);

use CFX5::System qw(assert_can_window);

use CFX5::FrameServ;

use CFX5::Commands qw(do_cmd do_cmd_quiet handle_rv parse_rv get_cmd_output);

use CFX5::CCLI qw(export_parser_conf);
use CFX5::CUEI;
use CFX5::LIST;

CFX5::Config::read_config();

use vars qw($mode $port $batch $report $name $outdir $state $session $post $multi_config $rundir
            @resfiles $viewer_port $remote_host $wid $control_port);

$mode='gui';
$post=1;

my @nonopt = parse_cmdline
  (
   \@ARGV,
   'ALLOW_NON_OPTION',
   'INCLUDE_STD',
   '-batch+' => sub {
     $mode='batch';
     $batch=$_[1];
   },
   '-graphics+' => \$Config{CUE_GRAPHICS},
   '-gr+' => '-graphics',
   -gui => sub { $mode='gui'; },
   -line => sub { $mode='line'; },
   -local => \$Config{CUE_ISLOCAL},
   '-local-root+' => sub {
     $Config{CUE_ISLOCAL}=1;
     conf_datadir(\$Config{CUE_ROOT}, "Local CUE root directory %%", @_);
   },
   '-m+' => '-multiconfig',
   '-multiconfig+' => sub {
     $multi_config=$_[1];
   },
   '-monitor+' => sub {
     $rundir=$_[1];
   },
   '-n+' => '-name',
   '-name+' => \$name,
   '-o+' => '-outdir',
   '-outdir+' => sub {
     conf_datadir(\$outdir, "CFD-Post report output directory %%", @_);
   },
   -nogui => sub {
     $mode='nogui';
   },
   '-play+' => '-session',
   -post => \$post,
   '-port+' => \$port,
   '-remote+' => sub {
     $mode='remote';
     $remote_host=$_[1];
   },
   '-r+' => '-report',
   '-report+' => sub {
     $mode='report';
     $report=$_[1];
   },
   '-res+' => '-results',
   '-results+' => sub {
     push @resfiles, $_[1];
   },
   '-f+' => '-results',
   '-run-with+' => \$Config{CFX_RUN_WITH},
   '-server' => sub { $mode='server'; },
   '-s+' => '-session',
   '-session+' => sub {
     $session=$_[1];
   },
   '-state+' => sub {
     $state=$_[1];
   },
   '-t+' => '-state',
   '-viewer-port+' => \$viewer_port,
   '-viewerport+' => '-viewer-port',
   '-wid+' => \$wid,
   '-control-port+' => \$control_port,
  );

exit_if_error();

if (@nonopt) {
  for my $f ( @nonopt ) {
    push @resfiles, $f;
  }
}

exit_if_error();

#
# argument consistency checks
#
if ($mode eq 'gui' ){
  _error("GUIs are not supported on this platform") unless check_gui_support();
  exit_if_error();
}

if ($mode eq 'remote') {
  _error("You must use the -port argument with -remote" . CFX5::Help::usage_msg_once())
    unless defined $port;
  _error("You must use the -viewer-port argument with -remote" . CFX5::Help::usage_msg_once())
    unless defined $viewer_port;
}
if (! defined $report) {
  _error("You must use the -report option with -name" . CFX5::Help::usage_msg_once())
    if defined $name;
  _error("You must use the -report option with -outdir" . CFX5::Help::usage_msg_once())
    if defined $outdir;
}
if ( defined $rundir ) {
  if ( defined $state ) {
    _error("The -monitor option cannot be combined with -state." . CFX5::Help::usage_msg_once());
  }
  if ( defined $session ) {
    _error("The -monitor option cannot be combined with -session." . CFX5::Help::usage_msg_once());
  }
  if ( @resfiles ne 0  ) {
    _error("The -monitor option cannot be combined with loading other results files." . CFX5::Help::usage_msg_once());
  }
}

exit_if_error();

#
# set up default values
#
$port=10_000 + ($$ % 10_000)
  unless defined $port;

#
# On DECs the _RLD_ARGS environemnt variable will be set if CFD-Post is
# started from CFX-Build. However the setting used by CFX-Build will
# cause CFX-Visualise to crash, and might affect post too. So we'll unset
# it.
#
delete $ENV{_RLD_ARGS};

if (!$post) {
  CFX5::CUEI::export_pre_conf();
} else {
  CFX5::CUEI::export_post_conf();
}
export_conf(qw(CFX_DATA_DIR CFX5ROOT CFX_CMD_DIR
               CFX_TOOLS_ROOT CFX_OS CFX5OS
               LM_LICENSE_FILE CFX_LICENSE_FILE
               CUE_DIR CFX5PERL
               ANSYS_COMMON_ROOT ANSYS_COMMON_IMAGES_DIR
              ));

# check for DISPLAY
assert_can_window() unless ( $mode eq 'batch' || $mode eq 'report' || $mode eq 'server' || $mode eq 'nogui' ) ;

exit_if_error();

CFX5::PrintConfig::show_vars_by_verbosity();

my @args;

for my $rf ( @resfiles ) {
  push @args, '-f', $rf;
}
if (defined $state) {
  push @args, '-t', $state;
}
if (defined $session) {
  push @args, '-s', $session;
}

if (defined $rundir) {
  push @args, '-i', $rundir;
}

if (defined $wid) {
  push @args, -w => $wid;
}

if (defined $control_port) {
  push @args, -x => $control_port;
}

if (defined $multi_config) {
  push @args, -m => $multi_config;
}

if (defined $report) {
  if (defined $outdir) {
    push @args, '-o' => $outdir;
  }
  if (defined $name) {
    push @args, '-n' => $name;
  }
}

my $run=$post ? "POST" : "PRE";

CFX5::FileTests::execfile($Config{"CUE_${run}ENGINE_EXE"},
                          "CFD-Post Engine executable ".$Config{"CUE_${run}ENGINE_EXE"});
#CFX5::FileTests::execfile($Config{"CUE_VIEWER_EXE"},
#                          "CFD-Post viewer executable ".$Config{CUE_VIEWER_EXE});
if ($mode eq 'gui') {
  CFX5::FileTests::execfile($Config{"CUE_${run}GUI_EXE"},
                            "CFD-Post GUI executable ".$Config{"CUE_${run}GUI_EXE"});
}

exit_if_error();

my @runwith;
if (defined $Config{CFX_RUN_WITH}) {
  @runwith = $Config{CFX_RUN_WITH};
}

if ($mode eq 'gui') {
  my $rv=handle_rv(do_cmd(@runwith, $Config{"CUE_${run}GUI_EXE"}, '-p', $port, @args));
  _warn("CFD-Post exited with return code $rv")
    if ($rv);
  exit($rv);
} elsif ($mode eq 'line') {
  my $rv=handle_rv(do_cmd(@runwith, $Config{"CUE_${run}ENGINE_EXE"}, '-v', @args));
  _warn("CFD-Post exited with return code $rv")
    if ($rv);
  exit($rv);
} elsif ($mode eq 'batch') {
  CFX5::Config::def->import(TASC_VIEWER_NOWINDOW => sub { '1'; });
  export_conf('TASC_VIEWER_NOWINDOW');
  my $rv=handle_rv(do_cmd(@runwith, $Config{"CUE_${run}ENGINE_EXE"}, '-v', '-b', '-session', $batch, @args));
  _warn("CFD-Post exited with return code $rv")
    if ($rv);
  exit($rv);
} elsif ($mode eq 'nogui') {
  CFX5::Config::def->import(TASC_VIEWER_NOWINDOW => sub { '1'; });
  export_conf('TASC_VIEWER_NOWINDOW');
  my $rv=handle_rv(do_cmd(@runwith, $Config{"CUE_${run}ENGINE_EXE"}, '-v', '-nogui', @args));
  _warn("CFD-Post exited with return code $rv")
    if ($rv);
  exit($rv);  
} elsif ($mode eq 'report') {
  CFX5::Config::def->import(TASC_VIEWER_NOWINDOW => sub { '1'; });
  export_conf('TASC_VIEWER_NOWINDOW');
  my $rv=handle_rv(do_cmd(@runwith, $Config{"CUE_${run}ENGINE_EXE"}, '-v', '-b', '-report', $report, @args));
  _warn("CFD-Post exited with return code $rv")
    if ($rv);
  exit($rv);
} elsif ($mode eq 'remote') {
  push @args, '-c', '-d', $remote_host, '-p', $port, '-v', $viewer_port;
  my $rv=handle_rv(do_cmd_quiet(@runwith, $Config{"CUE_${run}GUI_EXE"}, @args));
  _warn("CFD-Post exited with return code $rv")
    if ($rv);
  exit($rv);
} elsif ($mode eq 'server') {
  my $rv=handle_rv(do_cmd(@runwith, $Config{"CUE_${run}ENGINE_EXE"}, '-v', '-g', @args));
  _warn("CFD-Post exited with return code $rv")
    if ($rv);
  exit($rv);
} else {
  internal_error("Invalid mode specification $mode");
}
