#!/usr/bin/perl -w
package XXXXbuildenv;
{
# XXXXbuild-env.pl  wjs  Jun 04
# XXXX = "opt-" for option server setup; presumably empty else
#	(from opt-build-env November 13, 1998  C.Hammond
#	 "For use in setting a compilation environment when building
#	 an OTHER OPTIONS server" as modified by rcg 29 Dec 99
#	 Base csh source file was in use 1 Jun 04)

#	General comment: this routine is a string generator.  It does NOT
#    check for the validity of strings, existence of files when string
#    points to a file, etc.  I think this is a good architectural idea
#    because I don't think all strings can be validated, and doing some
#    but not others would be confusing
#
#	Accepts -sh or -csh switch.  If present, outputs a set of export or
#    setenv commands, respectively, to stdout.  Values for env vars are
#    output between a single set of "s, so complicated ones might produce
#    bad setenv/export statements.
#	Accepts -defnlist to control XXXXBUILD-ENV-DEFNS (see below)
#	Accepts an absolute directory spec as an argument.  If present, that 
#    directory becomes the jgofs root instead of the directory in which
#    opt-build-env is found.
#	If -defnlist specified, outputs XXXXBUILD-ENV-DEFNS, an 
#    environment variable = to a comma separated list of environment
#    variables set by XXXXbuild-env.pl.
#	Defines perl hash old_ENV for every env var that XXXXbuild-env.pl 
#    replaced.  Key is the replaced env var; value is the replaced value.
#    old-ENV{key} is undefined if there was no old value for key.

#	Sample of environment variables output - documentation is in code where
#	user modifies the site-specific value.  (Note: sample not
#	necessarily complete)
#	    Some variables (eg, TARPROG) are output only for option servers
#	    Some variables (eg, SHELL) are output on an OS-specific basis.
#	  AR		/usr/ccs/bin/ar srv
#	  BACKGROUND_COLOR	00FF00
#	  BUTTONIMAGESDIR	http://optserv1.whoi.edu:8200/images
#	  CC		cc -DSOL -DSVR4 -lnsl -lsocket
#	  CONFIG_FILE	/export/home/wsass/opt-build-env.pl
#	  DIRSERVER	optserv1.whoi.edu:8200/jg/dir
#	  DISPLAY_DATA_URL	FALSE
#	  DMONAME	Option Server
#	  FC		f77 -lnsl -lsocket
#	  GNUCOMPRESS	/usr/local/bin/gzip
#	  HELPADDR	http://optserv1.whoi.edu:8200
#	  HELPDIR	htdocs
#	  INFOSERVER	optserv1.whoi.edu:8200/jg/info
#	  JGOFSDIR	/export/home/wsass
#	  JGSCRIPTDIR	/jg
#	  MAIL_SENDER	/usr/bin/rmail
#	  MYADDR	optserv1.whoi.edu:8200
#	  NAWK		nawk
#	  OBJDIR	/
#	  OPT		opt
#	  OPTIONSERVER	optserv1.whoi.edu/jg/otheropt
#	  PERL		/usr/bin/perl
#	  PORT		8200
#	  RANLIB	echo
#	  SYS		Solaris
#	  TARPROG	/usr/bin/tar
#	  TEMPADDR	http://optserv1.whoi.edu:8200/jgofsopt/8200
#	  TEMPDIR	/export/home/wsass/htdocs/jgofsopt/8200
#	  UNIXCOMPRESS	/usr/bin/compress
#	  ZIPPROG	/usr/local/bin/zip


#  12 Jul 06.  wjs
#	BACKGROUND_COLOR; DISPLAY_DATA_URL
#  27 Sep 05.  wjs
#	Add some comments re jgofsopt per Bob's request
#  22 Jun 05.  wjs
#	Give up on fancy matlab list.
#	Add netcdf
#  17 Dec 04.  wjs
#	Define a mail program for OOserver
#   9 Dec 04.  wjs
#	The server document & cgi roots, and the "button images directory"
#	  are not logically connected to the JGOFS installation directory
#	  However, OOserver (at least download) installs help .html into
#	  HELPDIR, which must therefore be a subdir of the document root.
#	  Similarly, the OOserver temp directory must be a subdir of the
#	  document root.
#   2 Dec 04.  wjs
#	TEMPADDR
#  20 Aug 04.  wjs
#	Fiddle w/matlab_list defn.  Don't know what the pre-fiddle
#	  syntax meant, but apparently perl did!
#  16 Jul 04.  wjs
#	ENV{"PERL"} for backward compatibility
#	Add _LIB_LOC to MATLABx defns
#  29 Jun 04.  wjs
#	$ENV{"OPT"}.  "opt" if XXXXbuild-env.pl starts with opt-; "" else
#	  Looks at main pgm variable $::build_env_file_name; if undefined, uses $0
#	Default infoserver, dirserver, dir's object root, and default server
#	  name for JGOFS & GLOBEC programs
#   9 Jun 04.  wjs
#	Switches; argument; perl location.
#   4 Jun 04.  wjs
#	Stop supporting SunOS (saves us from having to figure out where
#	  ar is located, among other things)
#   1 Jun 04.  wjs
#	Change from csh to perl.
#	Add CONFIG_FILE - name of this file
#	  Derive JGOFSDIR from CONFIG_FILE instead of from `pwd`
#	Add dir spec to ar - seems to "move around"
#	Point TEMPDIR to htdocs/jgofsopt/PORT.  The fact that we
#	  alias that to /jgofsopt is irrelevant to the working of
#	  the software, and might not be something that an installer
#	  wants to do.  On the other hand, the web server will
#	  insist that jgofsopt be a subdir in the htdocs tree
#   5 May 04.  wjs
#	Add matlab library locations
#  12 Apr 04.  wjs
#	Mods for port 8200 wjs server.  Leave node as optserv1
#  29 Dec 1999. Use development file but change port to 80.  rcg
#  18 Nov 1999. clh add vars for download specifically, but may be useful
# 		for other scripts in system.
#  

  foreach (@ARGV) {
    if ($_ eq "-sh") {
      ((defined $sh_out) || (defined $csh_out)) && 
			die ("Duplicate or conflicting -sh, -csh switches\n");
      $sh_out = 1;
    } elsif ($_ eq "-csh") {
      ((defined $sh_out) || (defined $csh_out)) && 
			die ("Duplicate or conflicting -sh, -csh switches\n");
      $csh_out = 1;
    } elsif ($_ eq "-defnlist") {
      $defnlist = "";
    } else {
      (defined $jgofs_root) && die "Too many switches/arguments\n";
      $jgofs_root = $_;
    }
  }

  (defined $sh_out) || ($sh_out = 0);
  (defined $csh_out) || ($csh_out = 0);
  if (defined $jgofs_root) {
    ($jgofs_root =~ /^\//) ||
      die "jgofs root (specified as $jgofs_root) must be an absolute file spec\n";
    (-e $jgofs_root) || die "jgofs root $jgofs_root does not exist\n";
    (-r $jgofs_root) || die "jgofs root $jgofs_root is not readable\n";
    (-d $jgofs_root) || die "jgofs root $jgofs_root is not a directory file\n";
  }

###
# most only need to edit between long comment lines
#######################################################################

#   Operating system.  If not "Solaris", "Irix", or "linux"
#   editing "outside the lines" will be required
$opsys = "linux";

#   Location of perl.  It is recommended that this NOT be used
#   Some perl scripts are released as "template" files which are input
#     to make files which substitute values for placeholders in the template.
#     Except for the location of perl itself, these placeholders all come
#     from this file.  Therefore, we can get rid of both the templates and
#     their make files by
#	1) hardcoding the perl location (we recommend /usr/bin/perl and,
#	   if perl is NOT in /usr/bin, setting up a soft link defining
#	   /usr/bin/perl; eg, ln -s /usr/bin/perl wherever_perl_is)
#	2) "require"ing this file
#	3) using $ENV{"whatever"} instead of the placeholder
$perl_location = "/usr/bin/perl";
########

#   Next group must be defined and non-empty
#   $jgofs_cgi_root is relative to the directory this config file is in,
#     and must be defined in server config for $server_name:$port
$server_name = "mapservice-dev.whoi.edu";
$port = 80;
$jgofs_cgi_root = "jg";

#   Pieces of URL pointing to directory where images for outer's
#   display buttons are located.  Empty $button_images_server means
#   $server_name.  Empty $button_images_dir means default doc root for
#   $button_images_server.  (Note that empty $button_images_port means
#   default port for $button_images_server, not $port)
#   If no images, comment out next 3 lines
$button_images_server = "mapservice-dev.whoi.edu";
$button_images_port = "";
$button_images_dir = "images";

#	Next 2 values control appearance of web pages displayed by
#	outer.  If your methods do not use outer, these values have
#	no effect.
#   Controls whether outer displays the object spec as a title line 
#   in html display.  May be omitted.  Default value is TRUE
$display_data_url=TRUE;
#   Controls background color of pages displayed by outer.  May be
#   omitted.  Default value depends on browser displaying page.
#   If specified, specify as a string constant exactly 6 characters in
#   length, each character being a valid hex digit.  Case insensitive.
$background_color="808080";

#
#   Name of server (appears on web pages someplace...)
#   If commented out or otherwise undefined, defaults to $server_name
#   A defined, empty name is honored.  Will override the default server
#   name, if any, implied by the value of program (below)
$dmoname = "MapService-dev";

#	NEXT VARIABLE ONLY NEEDED FOR DATA SERVER SETUP
#   If you are a node in the JGOFS or GLOBEC programs, setting
#   program to JGOFS or GLOBEC, respectively, will set your documentation
#   and directory servers to the programs' master servers, and will
#   set the default name for your data server.  If blank or undefined,
#   servers will come from your node.
#		$program = "";


#	REST OF VARIABLES ONLY NEEDED FOR OPTION SERVER SETUP
#   Directory of DocumentRoot defined for $server_name in
#   server setup, specified as a relative directory (no initial /)
#   This directory must be an offset from the JGOFS software installation
#   directory (where this file lives).  Use links, if necessary, to
#   coordinate JGOFS installation tree and web server tree
$doc_root = "htdocs";

#   directory relative to $doc_root where help is located
$help_dir = "";

#   directory relative to $doc_root under which temp files are stored
#   Some level of uniqueness is nice, but we certainly don't do 
#   a thorough job of it with $port.  (We don't even do a
#   thorough job of it when we add the browser's ip addr as
#   another subdirectory level)
#   (NB: this is NOT /jgofsopt just because we sometimes alias 
#   things there - alias is logically irrelevant to configuration
#	The OOserver code uses jgofsopt in 2 different ways.  One way
#   is as a spec for temp files (set up here).  When used this way, the file
#   spec is arbitrary (except for accessibility issues).  The other way is 
#   as a web-server-accessibile "entity".  When used this way, jgofsopt 
#   is "the thing we define in the web server setup".  We happened to 
#   choose the same name for both uses (and, on optserv1, threw a file
#   system symbolic link into the stew for good measure)
#	Among other things, the web "entity" must be a subdir of the 
#   doc root (enforced here, creating an understood association between
#   what's done here and what's done in the web server config))
$temp_dir = "jgofsopt/$port";

#     Locations below are almost just "suggestions" to remind us that
#   this info, if changed, will goof things up.  These root locations
#   are just the start.  The actual directories, files, etc that are
#   needed are set in the make files.  We make the unjustified
#   assumption that what's needed in the make files will be a function
#   of these roots plus other, "observed" names, offsets, etc.
#     If option server being set up does not offer these services,
#   define symbol as empty string.  matlab5 stuff for option servers that would
#   like to offer a matlab version in addition to matlab v 5.  option
#   servers that only offer v 5 should set matlab5root to empty string
$matlabroot = "/usr/local/matlab";
$matlab5root = "";
$netcdfroot = "";

#   auxiliary programs required for download functionality
$mail_sender = "/usr/bin/rmail";
$zip = "/usr/bin/zip";
$tar = "/bin/tar";
$compress = "/usr/bin/compress";
$gzip = "/bin/gzip";

#######################################################################
# most only need to edit between long comment lines
###



###
#	OPERATING SYSTEM STUFF
###

$opsys || die "Undefined or blank \$opsys (operating system) variable";

if ( $opsys eq 'linux' ) {
  &out("CC","cc");
  &out("FC","g77 -O");
  &out("AR","/usr/bin/ar rv");
  &out("RANLIB","ranlib");
  &out("NAWK","awk");
#   Next line needed only for option servers that support matlab
#   Value determined by inspection of fleetlink.whoi.edu Jun 2005
  $matlab_extern_arch_dir = "glnx86";
#		      Stop supporting SunOS.  Leave this here to explain
#		      code conditional on SYS=SunOS (for example)
#		} elsif ( $ENV{'SYS'} eq 'SunOS' ) {
#		  $ENV{'CC'} = "cc -DSUN";
#		  $ENV{'FC'} = "f77";
#		  $ENV{'AR'} = "ar rv";
#		  $ENV{'RANLIB'} = "ranlib";
#		  $ENV{'NAWK'} = "nawk";
} elsif ( $opsys eq 'Solaris' ) {
  &out("CC","cc -DSOL -DSVR4 -lnsl -lsocket");
  &out("FC","f77 -lnsl -lsocket");
  &out("AR","/usr/ccs/bin/ar srv");
  &out("RANLIB","echo");
  &out("NAWK","nawk");
#   Next line needed only for option servers that support matlab
#   Value determined by inspection of gb6.whoi.edu Jun 2005
  $matlab_extern_arch_dir = "sol2";
} elsif ( $opsys eq 'Irix' ) {
  &out("CC","cc -cckr -DIRIX");
  &out("F77","f77 -woff 2290");
  &out("AR","/usr/bin/ar -srv");
  &out("RANLIB","echo");
  &out("NAWK","nawk");
  &out("SHELL","/sbin/sh");
#   Next line needed only for option servers that support matlab
#   Value from E Cunningham Jun 2005
  $matlab_extern_arch_dir = "sgi";
} else {
  die "Unrecognized value for \$opsys (operating system) variable: $opsys";
}
&out("SYS",$opsys);

&out("PERL",$perl_location);



###
#	JGOFS SYSTEM/WEB SERVER STUFF
###

(defined $program) || ($program = "");

$this_file = ($main::build_env_file_name) ? $main::build_env_file_name : $0;

#   Use cd command to get directory.  Don't know how to do it easily otherwise
#   (there is a shell env var PWD, but this can be set != to actual pwd)
($dir,$file) = ($this_file =~ /^(.*)\/(.+)$/);
if ($file) {
#   Presumably $dir must be defined if $file is, so testing $dir is
#   asking whether or not it's empty
  $this_dir = ($dir) ? `(cd $dir; pwd)` : "";
} else {
#   Presumably $dir is not defined, or we'd have a non-empty dir spec w/an
#   empty file name.  Don't think this is worth a diagnostic
  $this_dir = `pwd`;
  $file = $this_file;
}
chomp $this_dir;
&out("CONFIG_FILE","$this_dir/$file");

(defined $jgofs_root) || ($jgofs_root = $this_dir);

$opt_prefix = ($file =~ /^opt-/) ? "opt" : "";

if ($defnlist) {
  $defnlist_env_var = $opt_prefix;
  $defnlist_env_var && ($defnlist_env_var .= "-");
  $defnlist_env_var .= "BUILD-ENV-DEFNS";
}

#   Could do more checks on next group.  port should be numeric.
#   _root's should neither lead nor end w/slashes
$server_name || die ("\$server_name variable empty or undefined");
$port || die ("\$port variable empty or undefined");
$doc_root || die ("\$doc_root variable empty or undefined");
$jgofs_cgi_root || die ("\$jgofs_cgi_root variable empty or undefined");

#   Presence/absence of slashes, "http:"s, etc is historical.
#   So are most comments below.
#   Unfortunately not much consistency...
$myaddr = "$server_name:$port";

#   I suspect trouble if $jgofs_root is /.  Since things that use this
#   assume that $jgofs_root does not end in /, we'll put out the empty
#   string and hope for the best
&out("JGOFSDIR",$jgofs_root);

&out("OPT","$opt_prefix");
&out("PORT",$port);
&out("MYADDR",$myaddr);

#
# location to be added to MYADDR to find Optionserver scripts
# (and other stuff, like serv.  Probably not in use in data servers
# at the moment. wjs Jun 04)
#
&out("JGSCRIPTDIR","/$jgofs_cgi_root");

#   Deliberately allowing user to specify empty $button_images_dir
#   which means that images are in default doc root of server
if (defined $button_images_dir) {
  $button_images_server || ($button_images_server = $server_name);
  $button_images_port && ($button_images_port = ":$button_images_port");
  $temp = "http://$button_images_server$button_images_port";
  $button_images_dir && ($temp .= "/$button_images_dir");
  &out("BUTTONIMAGESDIR",$temp);
}

$option_server = "optserv1.whoi.edu/jg/otheropt";
$opt_prefix && ($option_server ne "$myaddr/$jgofs_cgi_root/otheropt") &&
	(warn "$this_file not being used to set up system OO server\n" .
	      "system OO server = $option_server\n" .
	      "server being set up = $myaddr/$jgofs_cgi_root/otheropt\n");
&out("OPTIONSERVER",$option_server);

#   Deliberately allowing user to specify empty $dmoname
if ($program eq "JGOFS") {
  $info_server = "usjgofs.whoi.edu/jg/info";
  $dir_server = "usjgofs.whoi.edu/jg/dir";
  (defined $dmoname) || ($dmoname = "US JGOFS");
  $objdir = "/jgofs";
} elsif ($program eq "GLOBEC") {
  $info_server = "globec.whoi.edu/jg/info";
  $dir_server = "globec.whoi.edu/jg/dir";
  (defined $dmoname) || ($dmoname = "U.S. GLOBEC");
  $objdir = "/globec";
} else {
  $info_server = "$myaddr/$jgofs_cgi_root/info";
  $dir_server = "$myaddr/$jgofs_cgi_root/dir";
  (defined $dmoname) || ($dmoname = "$server_name -- ");
  $objdir = "/";
}

(defined $background_color) && &out("BACKGROUND_COLOR",$background_color);
(defined $display_data_url) && &out("DISPLAY_DATA_URL",$display_data_url);

&out("INFOSERVER",$info_server);
&out("DIRSERVER",$dir_server);
&out("OBJDIR",$objdir);
&out("DMONAME",$dmoname);

if ($opt_prefix) {
#
#   HELPDIR is subdirectory from JGOFSDIR for help documents
#   HELPADDR is full URL to the location for help documents
#
  $temp = $doc_root;
  $help_dir && ($temp .= "/$help_dir");
  &out("HELPDIR",$temp);

  $temp = "http://$myaddr";
  $help_dir && ($temp .= "/$help_dir");
  &out("HELPADDR",$temp);

#
#   TEMPDIR/TEMPADDR are similar but, alas, not same as
#   HELPDIR/HELPADDR.
#      TEMPDIR is absolute dir spec to
#   a temporary directory unique to OOserver on this port
#   (HELPDIR is a relative directory)
#      TEMPADDR is URL of that directory, which depends
#   on TEMPDIR being a subdir of $jgofs_root/$doc_root
#   (HELPADDR works on same concept)
#      Note that the soft link from $doc_root/jgofsopt
#   to top-level /jgofsopt is NOT necessary (but I think
#   some code accidentally works because of it)
#
  $temp = "$jgofs_root/$doc_root";
  $temp_dir && ($temp .= "/$temp_dir");
  &out("TEMPDIR",$temp);

  $temp = "http://$myaddr";
  $temp_dir && ($temp .= "/$temp_dir");
  &out("TEMPADDR",$temp);

  if ($matlabroot) {
    ($incdir,$libdir) = &do_matlab($matlabroot,$matlab_extern_arch_dir);
    &out("MATLABINCDIR",$incdir);
    &out("MATLABLIBDIR",$libdir);
  }
  if ($matlab5root) {
    ($incdir,$libdir) = &do_matlab($matlab5root,$matlab_extern_arch_dir);
    &out("MATLAB5INCDIR",$incdir);
    &out("MATLAB5LIBDIR",$libdir);
  }

  if ($netcdfroot) {
    ($incdir,$libdir) = &do_netcdf($netcdfroot);
    &out("NETCDFINCDIR",$incdir);
    &out("NETCDFLIBDIR",$libdir);
  }

  &out("MAIL_SENDER",$mail_sender);
  &out("ZIPPROG",$zip);
  &out("TARPROG",$tar);
  &out("UNIXCOMPRESS",$compress);
  &out("GNUCOMPRESS",$gzip);
}

#   Refer to $old_ENV to avoid "only one use" diagnostic
(exists $old_ENV{"JGOFSDIR"}) && 1;
1;
}
1;

sub do_matlab
#     "extern" strings empirically observed and assumed to be constant
#   for all matlab releases
#     Fooling with leading and trailing slashes may not be necessary.
#   In any case, objective is 1) make the cc options -L & -I happy
#   &  2) make LD_LIBRARY_PATH happy.  At minimum, objective should
#   be to put out a consistent string whether or not user plays with
#   slashes
{
  my ($root,$suffix) = @_;
  my ($save_chomp_char);

  $save_chomp_char = $/;
  $/ = '/';
  chomp $root;
  chomp $suffix;
  ($suffix) = ($suffix =~ m"^/?(.*)");
  $/ = $save_chomp_char;

  return "$root/extern/include" , "$root/extern/lib/$suffix";
}

sub do_netcdf
#     See do_matlab comments above
#     This routine not really needed, but makes a parallel w/matlab...
{
  my ($root) = @_;
  my ($save_chomp_char);

  $save_chomp_char = $/;
  $/ = '/';
  chomp $root;
  $/ = $save_chomp_char;

  return "$root/include" , "$root/lib";
}

sub out
{
  my ($env_var,@env_var_val) = @_;
  my ($env_var_val);

  (scalar @env_var_val > 0) || die "No value for env var $env_var\n";

  $env_var_val = join (' ',@env_var_val);

  $sh_out && (print "export $env_var=\"$env_var_val\"\n");
  $csh_out && (print "setenv $env_var \"$env_var_val\"\n");
  if (defined $defnlist) {
    $defnlist && ($defnlist .= ",");
    $defnlist .= $env_var;
    $ENV{$defnlist_env_var} = $defnlist;
  }
#   If we are about to change an env var, save it... but only save
#   the first one (protects in case this routine for some reason
#   changes something more than once - we want the "original")
  if (exists $ENV{$env_var}) {
    (exists $old_ENV{$env_var}) || ($old_ENV{$env_var} = $ENV{$env_var});
  }
  $ENV{$env_var} = $env_var_val;
  return;
}
