#code to launch both dbconsole and agent.
#Created by : kduvvuri
#Date created: 06/17/2004
package LaunchEMdbconsole;
use EmCommonCmdDriver;
use EmctlCommon;
use DBConsole;
use LaunchEMagent;
use IPC::Open3;
use Symbol qw(gensym);
use Config;

$EMHOME=getEMHome($ENV{CONSOLE_CFG});
$EM_OC4J_HOME=getOC4JHome($ENV{CONSOLE_CFG});
sub new {
  my $classname = shift;
  my $self = {} ;
  bless ( $self, $classname);

  return $self;
}

sub doIT {
   my $self = shift;
   $refCmds = $self->{cmds};
   $cmdDriver = EmCommonCmdDriver->new();
   $result = $cmdDriver->doIT($refCmds, \@_);
   return $result;
}

#Launches DBConsole and agent. Returns the results back to emwd.pl so that
#monitor function of the emwd.pl can make use of this to monitor the 
#health of the agent + dbconsole.
sub launchComp {
   my $classname = shift;
   my $rargs = shift;

   # If omsRecvDir is set, OMS is local and both OMS+agent will be started
   # If it is present but commented, OMS is remote and only agent will b e started
   # If it is not present, default ot start both OMS+agent
   $OMS_RECV_DIR_SET = EmctlCommon::isOmsRecvDirSet();
   printMessage("omsRecvDir is set? =  $OMS_RECV_DIR_SET");

   if ($OMS_RECV_DIR_SET) {
   # launches and stats the Console Process.
   # Returns Return PID[0], Start time[2]....
   $temp = launchDBConsole();
   @consolePID = @$temp;

   #print "Console PID is $consolePID[0]\n";
   $console = new DBConsole();
   $console->Initialize($consolePID[0], $consolePID[1], $DEBUG_ENABLED);
   @consoleRow = ($console, \&launchDBConsole);
   }

   #Also start the agent..
   $agentObj = LaunchEMagent->new();
   $refAgentLaunch = $agentObj->launchComp();
   @agentRow = @$refAgentLaunch;

   if ($OMS_RECV_DIR_SET) {
   @ReferenceTable = (@consoleRow,@agentRow);
   }
   else
   {
       @ReferenceTable = (@agentRow);
   }

   return (\@ReferenceTable);
}


# launchDBConsole
# Launches the DBConsole process.
#
# Returns
# Array {
#            PID, # PID if Successful, <0 if failure
#            startTime # Starttime [or failure time]
#       }
#
sub launchDBConsole()
{
  my @returnArray = ();
  my ($CONSOLE_CHILD_PROCESS, $startTime);
  my $sid =  $ENV{'ORACLE_SID'};
  my $oh  =  $ENV{'ORACLE_HOME'};
  my $oracleUnqname = &DBConsole::getOracleUniqueName($oh,$sid);
  my $javaBatFile = "";

  if(defined($oracleUnqname))
  {
        $javaBatFile = $oh."/bin/execjavatemp".$oracleUnqname.".bat";
  }
  elsif(defined($sid))
  {
        $javaBatFile = $oh."/bin/execjavatemp".$sid.".bat";
  }
  else
  {
	$javaBatFile = $oh."/bin/execjavatemp.bat";	
  }
  # At the outset we need to fork, since we have to launch the
  # console in a different process...

  # If IS_WINDOWS then we need to use win32 perl libraries to fork/exec
  # Because the commandString is too long, we have to save the string into a .bat file. Then
  # pass the .bat file into the open3. Otherwise, the open3 will fail.
  if($IS_WINDOWS eq "TRUE")
  {
    my($commandString) = getDBConsoleLaunchCmd();
    system ("echo $commandString > $javaBatFile");
   
    $NOHUP_FILE = $ENV{'NOHUP_FILE'};
    
    $CONSOLE_CHILD_PROCESS = open3(gensym, ">&STDOUT", ">&STDERR", "$javaBatFile");
  }
  else
  {
    $CONSOLE_CHILD_PROCESS = fork();
  }

  if( $CONSOLE_CHILD_PROCESS == 0 )
  {
    # This is the child process... we exec the java...
    execDBConsoleProcess();
    exit 0;
  }
  else
  {
    # This is the parent process ...
    $startTime = time; # Record the time of launching the console...
    
    my($tempString) = "Console Launched with PID ".$CONSOLE_CHILD_PROCESS.
                      " at time ".localtime($startTime);
    printMessage($tempString);

    # Update the PID_FILE
    system("echo $CONSOLE_CHILD_PROCESS > $PID_FILE");

    (@returnArray) = ($CONSOLE_CHILD_PROCESS, $startTime);

    # If IS_WINDOWS then we need to remove $javaBatFile
    #
    # DO NOT remove the $javaBatFile.  If this file is removed, the cmd process will return an error code,
    # and the emwd.pl watchdog script will always believe that DBContrl exited with an error.  
    # The reason that the cmd process will return error is because it's not able to read 
    # the bat file after the java process terminates.
    #
#    if($IS_WINDOWS eq "TRUE")
#    {
#      system ("rm $javaBatFile");
#    } 

    return (\@returnArray);
  }
}

#
# execDBConsoleProcess.
# Execs the onsoleLaunchCmd returns the commandline for
# DB Execution
#
sub execDBConsoleProcess()
{
  $ENV{JAVA_HOME} = $JAVA_HOME;

  my($command) = getDBConsoleLaunchCmd();

  exec ($command);
}


sub getDBConsoleLaunchCmd()
{
  #printMessage("EMHOME from ConsoleLaunchCMD is $EMHOME\n");
  #printMessage("ORACLE_HOME is   $ORACLE_HOME\n");

  my $def_heap_size = "192M";
  my $def_perm_size = "200M";   

  my $heap_size = -1;
  my $perm_size = -1;

  # get heap size values from emoms.properties
  my $prop_file = "$EMHOME/sysman/config/emoms.properties";

  open(PROPFILE, "$prop_file");
  while(my $line = <PROPFILE>)
  {
    if ($line =~ m/^\s*oracle.sysman.dbc.heapSize=(.*)/i) 
    {
      $heap_size = $1;
    }  
    elsif ($line =~ m/^\s*oracle.sysman.dbc.permSize=(.*)/i)
    {
      $perm_size = $1;
    }
  }
  close(PROPFILE);

  if ($heap_size != -1)
  {
    $def_heap_size = $heap_size;
  }

  if ($perm_size != -1)
  {
    $def_perm_size = $perm_size;
  }

  my $joptions = "$EM_SOL_JAVA -server -Xmx$def_heap_size -XX:MaxPermSize=$def_perm_size " .
      "-XX:MinHeapFreeRatio=20 -XX:MaxHeapFreeRatio=40 ";
  my $headlessopt = "-Djava.awt.headless=true";

  printMessage("osname is $^O");

  if (lc($^O) eq "aix" or $Config{'archname'} =~ m/s390x-linux/) 
  {
    $def_heap_size = "384M";

    if ($heap_size == -1)
    {
        $heap_size = $def_heap_size;
    }

    $joptions = "-Xmx$heap_size";

    if (lc($^O) eq "aix")
    {
      my $jver = `$JAVA_HOME/bin/java -version 2>&1`;
      $headlessopt = "" if $jver =~ m/1.4.1/;
    }
  }

 # This is for Linux_x86_64 ( Linux AMD )
  if ( $Config{'archname'} =~ /x86_64-linux-thread-multi/ or $Config{'archname'} =~ /ppc-linux-thread-multi/ or $Config{'archname'} =~ /^IA64/ ) 
  {
     $def_heap_size = "384M";
     $def_perm_size = "400M";

     if ($heap_size == -1)
     {
       $heap_size = $def_heap_size;
     }
     if ($perm_size == -1)
     {
       $perm_size = $def_perm_size;
     }

     $joptions = "-server -Xmx$heap_size -XX:MaxPermSize=$perm_size " .
        "-XX:MinHeapFreeRatio=20 -XX:MaxHeapFreeRatio=40 ";
  }
  
  if ( $Config{'archname'} =~ /sun4-solaris-thread-multi/ )
  {
     $def_heap_size = "384M";
     $def_perm_size = "400M";

     if ($heap_size == -1)
     {
       $heap_size = $def_heap_size;
     }
     if ($perm_size == -1)
     {
       $perm_size = $def_perm_size;
     }

     $joptions = "-server -Xmx$heap_size -XX:MaxPermSize=$perm_size " .
        "-XX:MinHeapFreeRatio=20 -XX:MaxHeapFreeRatio=40 ";
  }

  if ($Config{'archname'} =~ /solaris-thread-multi-64/ )
  {
     $EM_OC4J_OPTS = " -d64 " . "$EM_OC4J_OPTS ";
  }

  if ($Config{'osname'} == "solaris")
  {
	$cmdStr = "isainfo -b";
	$exVal = qx/$cmdStr/;
	chomp($exVal);
	if( $exVal == "64")
	{
		$def_heap_size = "384M"; 
		$def_perm_size = "400M"; 

	     if ($heap_size == -1)
	     {
	       $heap_size = $def_heap_size;
	     }
	     if ($perm_size == -1)
	     {
	       $perm_size = $def_perm_size;
	     }

	     $joptions = "$EM_SOL_JAVA -server -Xmx$heap_size -XX:MaxPermSize=$perm_size " .
        "-XX:MinHeapFreeRatio=20 -XX:MaxHeapFreeRatio=40 ";
	}
  }

  if ($Config{'osname'} == "hpux")
  {
     if($Config{'archname'} =~ /^PA-RISC/)
      {
        $cmdStr2 = "getconf HW_CPU_SUPP_BITS";
        $exVal2 = qx/$cmdStr2/;
        chomp($exVal2);
        if( $exVal2 == "64")
        {
                $def_heap_size = "384M"; 
                $def_perm_size = "400M"; 

             if ($heap_size == -1)
             {
               $heap_size = $def_heap_size;
             }
             if ($perm_size == -1)
             {
               $perm_size = $def_perm_size;
             }

             $joptions = "-server -Xmx$heap_size -XX:MaxPermSize=$perm_size " .
        "-XX:MinHeapFreeRatio=20 -XX:MaxHeapFreeRatio=40 ";
        }
     }
  }

  if ($Config{'osname'} == "MSWin32")
  {
     my $processor  = "x86";
   
     if (defined($ENV{'PROCESSOR_ARCHITECTURE'}))
     {
        $processor = $ENV{'PROCESSOR_ARCHITECTURE'};
     }
     if (defined($ENV{'PROCESSOR_ARCHITEW6432'}))
     {
        $processor = $ENV{'PROCESSOR_ARCHITEW6432'};
     }
     if ($processor =~ m/AMD64/ or $processor =~ m/IA64/)
     {
		$def_heap_size = "384M"; 
                $def_perm_size = "400M"; 

             if ($heap_size == -1)
             {
               $heap_size = $def_heap_size;
             }
             if ($perm_size == -1)
             {
               $perm_size = $def_perm_size;
             }

             $joptions = "-server -Xmx$heap_size -XX:MaxPermSize=$perm_size " .
        "-XX:MinHeapFreeRatio=20 -XX:MaxHeapFreeRatio=40 ";

     }
  }
 
  my $EM_DEV_MODE_OC4J_OPTS = "";
  my $devModeOptsFile = "$ORACLE_HOME/emdb/devMode_JVM_OPTS.emdbsa";
  if(-e $devModeOptsFile)
  {
    open(DEV_OPTS_FILE_READER, $devModeOptsFile);
    if(defined DEV_OPTS_FILE_READER)
    {
      my @dev_optlines;
      my $dev_optline = "";
      while($dev_optline = <DEV_OPTS_FILE_READER>)
      {
        chomp($dev_optline); 
        push(@dev_optlines,$dev_optline);
      }
      
      close DEV_OPTS_FILE_READER;

      foreach $dev_optline (@dev_optlines)
      {
        $EM_DEV_MODE_OC4J_OPTS = $EM_DEV_MODE_OC4J_OPTS . $dev_optline . " ";
      }
    } 
  }

  if (lc($^O) eq "dec_osf")
  {
    $def_heap_size = "384M";

    if ($heap_size == -1)
    {
        $heap_size = $def_heap_size;
    }  
    $joptions = "-server -Xmx$heap_size";
  }

  printMessage("heap size used is $heap_size");
  printMessage("perm size used is $perm_size");
  printMessage("joptions used are $joptions");
  
  return "$JAVA_HOME/bin/java $joptions " .
         "$EM_OC4J_OPTS " .
         "$EM_DEV_MODE_OC4J_OPTS " .
         "-DORACLE_HOME=$ORACLE_HOME " .
         "-Doracle.home=$ORACLE_HOME"."/oc4j ".
         "-Doracle.oc4j.localhome=$FORMFACTOR_BASE ".
         "-DEMSTATE=$EMHOME " .
         "-Doracle.j2ee.dont.use.memory.archive=true " .
         "-Djava.protocol.handler.pkgs=HTTPClient " .
         "-Doracle.security.jazn.config=$EM_OC4J_HOME/config/jazn.xml " .
         "-Djava.security.policy=$EM_OC4J_HOME/config/java2.policy " .
         "-Djavax.net.ssl.KeyStore=$ORACLE_HOME/sysman/config/OCMTrustedCerts.txt" .
         "-Djava.security.properties=$ORACLE_HOME/oc4j/j2ee/home/config/jazn.security.props " .
         "-DEMDROOT=$EMHOME " .
         "-Dsysman.md5password=true " .
         "-Drepapi.oracle.home=$ORACLE_HOME " .
         "-Ddisable.checkForUpdate=true " .
         "-Doracle.sysman.ccr.ocmSDK.websvc.keystore=$ORACLE_HOME/jlib/emocmclnt.ks " .
         "-Dice.pilots.html4.ignoreNonGenericFonts=true " .
         "$headlessopt " .
         "-jar $ORACLE_HOME/$OC4JLOC"."j2ee/home/oc4j.jar " .
         "-config $EM_OC4J_HOME/config/server.xml";
}

# printMessage
# prints EMWD trace messages
# The general format is
# ------ <localtime>::<message> ----- \n
#
sub printMessage()
{
 my ($message) = @_;
 print "----- ".localtime()."::".$message." -----\n";
}


sub DESTROY {
    my $self = shift;
}

1;
