#!/usr/bin/perl
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 2001,2019 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 
# sccsid = "@(#)81   1.20   src/rsct/rm/ConfigRM/cli/bin/lsrpdomain.perl, configrmcli, rsct_rady, rady2035a 7/5/17 02:46:35"
######################################################################
#                                                                    #
# Module: lsrpdomain                                                 #
#                                                                    #
# Purpose:                                                           #
#   lsrpdomain - lists RSCT peer domain information for the node.    #
#                                                                    #
# Syntax:                                                            #
#   lsrpdomain  [-h]  [-o|-O]  [-l|-t|-d|-D Delimiter] [-x] [-TV]    #
#               [PeerDomain]                                         #
#                                                                    #
# Flags:                                                             #
#   -h      Help. Writes the command's usage statement to standard   #
#           output.                                                  #
#   -o      Online peer domain.  List only information about the     #
#           online peer domain for the node.                         #
#   -O      Offline peer domains.  List only information about peer  #
#           domains for the node that are offline (not online).      #
#   -l      Long formatted output.  The peer domain information is   #
#           displayed on separate lines.                             #
#   -t      Tabular formatted output.  The peer domain information   #
#           is displayed in separate columns.                        #
#   -d      Delimiter-formatted output.  The default delimiter is a  #
#           colon (:).  Use the -D flag if you wish to change the    #
#           default delimiter.                                       #
#   -D Delimiter   Delimiter-formatted output that uses the specified#
#           delimiter.  Use this flag to specify something other     #
#           than the default colon (:).  An example is when the data #
#           to be displayed contains colons.  Use this flag to       #
#           specify a delimiter of one or more characters.           #
#   -x      Exlude header.  Suppress header printing.                #
#   -T      Trace. Writes the command's trace messages to standard   #
#           error. For your software-service organization's use only.#
#   -V      Verbose. Writes the command's verbose messages to        #
#           standard output.                                         #
#                                                                    #
# Operands:                                                          #
#   PeerDomain  The name of the peer domain to be listed. PeerDomain #
#           may be a peer domain name or a substring of a peer       #
#           domain name.  When it is a substring, any defined peer   #
#           domain name that contains the substring will be listed.  #
#                                                                    #
# Description:                                                       #
#   The lsrpdomain command lists information about the peer domains  #
#   to which the node where the command runs belongs.  The flags and #
#   operands can be used to specify what is listed.  When a peer     #
#   domain name is specified, the listed information is limitted to  #
#   that peer domain information only.  The -o or -O flag also       #
#   limits the listed information. The -o flag lists only the online #
#   peer domain's information.  The -O flag lists information for    #
#   peer domains that are not online.                                #
#                                                                    #
#                                                                    #
# Exit Values:                                                       #
#   0  CRM_CLI_SUCCESS       Command completed successfully.         #
#   1  CRM_CLI_RMC_ERROR     Command terminated due to an underlying #
#                            RMC error.                              #
#   2  CRM_CLI_ERROR         Command terminated due to an underlying #
#                            error in the command script.            #
#   3  CRM_CLI_BAD_FLAG      Command terminated due to user          #
#                            specifying an invalid flag.             #
#   4  CRM_CLI_BAD_OPERAND   Command terminated due to user          #
#                            specifying a bad operand.               #
#   5  CRM_CLI_USER_ERROR    Command terminated due to a user error, #
#                            for example specifying a name that      #
#                            already exists.                         #
#                                                                    #
# Examples:                                                          #
#                                                                    #
# Man Page:                                                          #
#   For the most current detailed description of this command see    #
#   the lsrpdomain man page in /opt/rsct/man.                   #
#                                                                    #
#--------------------------------------------------------------------#
# Inputs:                                                            #
#   /opt/rsct/msgmaps/configrmcli.lsrpdomain.map -              # 
#       message mapping                                              #
#                                                                    #
# Outputs:                                                           #
#   stdout - none.                                                   #
#   stderr - any error message.                                      #
#                                                                    #
# External Ref:                                                      #
#   Commands: ctdspmsg                                               #
#   Modules:  CRM_cli_utils.pm, CRM_cli_rc.pm,                       #
#             CRM_cli_include.pm, CT_cli_utils.pm                    #
#   Perl library routines: Getopt::Std                               #
#                                                                    #
# Tab Settings:                                                      #
#   4 and tabs should be expanded to spaces before saving this file. #
#   in vi:  (:set ts=4  and   :%!expand -4)                          #
#                                                                    #
# Change Activity:                                                   #
#   010806 JAC 75435: Initial design & write.                        #
#   011008 JAC 75442: Final version.                                 #
#   011029 JAC 77829: Change RSCTVersion to RSCTActiveVersion        #
#   020107 JAC 77329: Display security attrs (but not really)        #
#   020201 JAC 79963: switch to use lsrsrc-api instead of lsrsrc.    #
#   020206 JAC 80077: Add NLS support for heading and xlate values.  #
#   020207 JAC 80121: Make printing of c-api results a trace msg.    #
#   020207 JAC 80133: Issue not found message if a cluster specified.#
#   020227 JAC 80700: Get -a and -n flags to work.                   #
#   020420 JAC 82248: Change lscluster to lsrpdomain.                #
#   020428 JAC 82316: Call process_exit_code to check $rc.           #
#   020502 JAC 82564: Set local scope before calling lsrsrc-api.     #
#   020724 JAC 85045: Change -a|-n to -o|-O for cmd consistency.     #
#   040407 JAC 105863: Use escape_chars for "\" searches.            #
#   040422 JAC 108194: Use escape_selstr for cluster names and use   #
#                      LIKE in select string.                        #
#   050406 JAC 119510: Add rc when calling process_api_error.        #
######################################################################

#--------------------------------------------------------------------#
# General Program Flow/Logic:                                        #
#                                                                    #
# 1. Setup attributes to list with the command.                      #
# 2. Parse command line flags and operands.                          #
# 3. Print usage if -h specified                                     #
# 4. Setup a selection string if a cluster name operand was          #
#    specified.                                                      #
# 5. List the cluster information used the RMC lsrsrc command.       #
#    Also pass along -VT if necessary.                               #
# 6. Return back any errors from lsrsrc.                             #
# 7. Format the output into a 2D array so a utility can be used.     #
# 8. Set the type of output to display (long, table, ...).           #
# 9. Call the set_display utility to display the output.             #
#                                                                    #
#--------------------------------------------------------------------#

#--------------------------------------------------------------------#
# Included Libraries and Extensions                                  #
#--------------------------------------------------------------------#
use lib "/opt/rsct/pm";
use locale;
use Getopt::Std;

use CT_cli_utils qw(printIMsg
                    printEMsg);

use CT_cli_display_utils qw(set_display);

use CT_cli_input_utils qw(escape_chars);

use CRM_cli_rc qw(CRM_CLI_SUCCESS CRM_CLI_RMC_ERROR
                  CRM_CLI_ERROR CRM_CLI_BAD_FLAG
                  CRM_CLI_NOT_FOUND
                  CRM_CLI_BAD_OPERAND CRM_CLI_USER_ERROR);
use CRM_cli_utils qw(error_exit
                     printCIMsg
                     printCEMsg
                     getIMsg
                     process_api_error
                     process_exit_code
                     escape_selstr
                     lookup_yesno
                     lookup_opstate);
use CRM_cli_include qw($TRUE $FALSE
                       $RSCLUSTER $RMC_CLI_USER_ERROR
                       $RMC_OPSTATE_ONLINE
                       $RMC_CLI_RSRC_NOT_FOUND
                       $DELIMITER $LOCAL_SCOPE
                       $CTBINDIR $CTDIR);

#--------------------------------------------------------------------#
# Global Constants                                                   #
#--------------------------------------------------------------------#

#CAA cluster domain type
$Domain_Type_CAA = 1;

# attribute names
$Attr_name = "Name";
$Attr_rsctversion = "RSCTActiveVersion";
$Attr_mixedversions = "MixedVersions";
$Attr_tsport = "TSPort";
$Attr_gsport = "GSPort";
#$Attr_rmcport = "RMCPort";
#$Attr_resources = "ResourceClasses";
$Attr_opstate = "OpState";
#$Attr_configch = "ConfigChanged";
#$Attr_keytype = "CSSKType";
#$Attr_refresh = "CSSKRefreshInterval";
#$Attr_adminid = "AdminID";
$Attr_domaintype = "DomainType";

$lsr_attr_names = $Attr_name;
$lsr_attr_names .= "::$Attr_opstate";
#$lsr_attr_names .= $Attr_configch . " ";
$lsr_attr_names .= "::$Attr_rsctversion";
$lsr_attr_names .= "::$Attr_mixedversions";
$lsr_attr_names .= "::$Attr_tsport";
$lsr_attr_names .= "::$Attr_gsport";
$lsr_attr_names .= "::$Attr_domaintype";
#$lsr_attr_names .= $Attr_rmcport . " ";
#$lsr_attr_names .= $Attr_keytype . " ";
#$lsr_attr_names .= $Attr_refresh . " ";
#$lsr_attr_names .= $Attr_adminid . " ";

#--------------------------------------------------------------------#
# Global Variables                                                   #
#--------------------------------------------------------------------#
$Trace = $FALSE;                        # default - trace off
$Verbose = $FALSE;                      # default - verbose turned off
$Opt_Delm_Format = $FALSE;              # default - no delimited output
                                        #         -d, -D flags
$Opt_Delm_Str = ":";                    # default - delimiter character
                                        # can be overridden with -D flag
$Opt_Long_Format = $FALSE;              # default - long formatted output
$Opt_Table_Format = $TRUE;              # default - tabular format 
$Opt_No_HDR = $FALSE;                   # default - do not supress heading
                                        # output, -x flag
$Opt_Only_Online = $FALSE;              # default - do not list only      
                                        # the online cluster
$Opt_Only_NotOnline = $FALSE;           # default - do not list only the
                                        # clusters that are not online

$PROGNAME = "lsrpdomain";               # Program Name for messages
$LSMSG = "$CTBINDIR/ctdspmsg";          # list / display message rtn
$MSGCAT = "configrmcli.cat";            # msg catalogue for this cmd
$ENV{'MSGMAPPATH'} = "$CTDIR/msgmaps";  # msg maps used by $LSMSG

#--------------------------------------------------------------------#
# Variables                                                          #
#--------------------------------------------------------------------#
my $cluster_name = "";                  # cluster to list
my $cluster_name_orig = "";             # cluster to list
my $name_select = "";                   # selection string for name
my $opstate_select = "";                # selection string for opstate
my @lsr_out = ();                       # output from lsrsrc            
my @lsr_out2 = ();                      # copy of output from lsrsrc            
my @lof_clusters = ();                  # 2D array to be displayed      
my $attr_name = "";                     # an attribute name
my @attr_names = ();                    # all attribute names
my $attr_val = "";                      # an attribute value
my @attr_vals = ();                     # all attribute values
my $line = "";                          # one line of output
my $i = 0;                              # array index
my $j = 0;                              # array index
my $row_count = 0;                      # number of display rows
my $col_count = 0;                      # number of display columns
my $display_type = "";                  # type of display call
my $opstate_index = 2;                  # output index for opstate
my $mixedvers_index = 4;                # output index for mixed versions
my $tsport_index = 5;			# output index for tsport
my $gsport_index = 6;			# output index for gsport
my $domaintype_index = 7;		# output index for domain type
my $refresh_index = 8;                  # output index for refr interval
my @heading = ();                       # heading for the listed data
my @noyestext = ();                     # for translating no/yes
my @opstatetext = ();                   # for translating opstate
my %op_states = ();                     # hash for opstate descriptions

my $passopts = "";                      # TV options to pass to RMC CLI
my $other_opts = "";                    # parameters to pass to RMC CLI
#--------------------------------------------------------------------#
# Main Code                                                          #
#--------------------------------------------------------------------#
my $rc = 0;
my $config_rc = 0;

# set local scope
$ENV{CT_MANAGEMENT_SCOPE} = $LOCAL_SCOPE;

# parse the command line, exit if there are errors 
($rc, $cluster_name) = &parse_cmd_line;
($rc == 0) || error_exit($rc);

if ($Verbose) { printIMsg("IMsglsrpdomainStart"); }

if ($Trace) { $passopts = $passopts." -T"; }
if ($Verbose) { $passopts = $passopts." -V"; }

# Do some escaping on strings.  Do the escape character first
# for anything that's a string, escape any inner \
#$cluster_name =~ s/\\/\\\\/g;

# for anything that's a string, escape any inner double quotes
#$cluster_name =~ s/\"/\\\"/g;

$cluster_name_orig = $cluster_name;
$cluster_name = escape_chars($cluster_name);
$cluster_name = escape_selstr($cluster_name);

# if a cluster name was entered, build a select clause
if ($cluster_name ne "") {
   # $name_select = "-s ${RSCLUSTER}::\"Name ?= \\\"$cluster_name\\\"\"";
   $name_select = "-s ${RSCLUSTER}::\"Name LIKE \\\"%${cluster_name}%\\\"\"";
} 

# for no name, use -o
else {
   $name_select = "-o ${RSCLUSTER}";
} 

# call lsrsrc
if ($Trace) { print STDERR "$PROGNAME: calling lsrsrc-api\n";}

#@lsr_out = `$CTBINDIR/lsrsrc -x -D $DELIMITER $passopts $name_select $RSCLUSTER $lsr_attr_names`;
@lsr_out = `$CTBINDIR/lsrsrc-api -D $DELIMITER ${name_select}::::::${lsr_attr_names} 2>&1`;

# capture the return code from lsrsrc
$rc = $?;
$rc = process_exit_code($rc);

if ($Trace) { print STDERR "lsrsrc-api results:\n";
              print STDERR "@lsr_out";}

if ($Trace) { print STDERR "$PROGNAME: lsrsrc-api returned $rc\n";}

# show any errors if there was a bad rc
if (($rc != 0) && ($rc != $RMC_CLI_RSRC_NOT_FOUND)) {
   process_api_error($DELIMITER,$rc,@lsr_out);
}

# return ConfigRM CLI user error if it's an RMC CLI user error
if ($rc == $RMC_CLI_USER_ERROR) { exit(CRM_CLI_USER_ERROR);}

# return OK if resource not found error, unless a cluster name was specified
if ($rc == $RMC_CLI_RSRC_NOT_FOUND) {
   if ($cluster_name eq "") { exit(0);}
   else {
      printEMsg("EMsglsrpdomainClusterNotFound",$cluster_name_orig);
      exit(CRM_CLI_NOT_FOUND);
   }
}

# if lsrsrc failed for something else, print RMC error message and exit
if ($rc != 0) {
#   printCEMsg("EMsgConfigRMcliUnExpectRMCrc",$rc);
    exit(CRM_CLI_RMC_ERROR);
    }
# The following section modifies each record for CAA domain and filters output based o

@lsr_out2 = @lsr_out;
@lsr_out = ();

foreach $line (@lsr_out2) {
   chomp($line);

   # parse the output
   @attr_vals = split(/$DELIMITER/, $line);

   # Checking if Domain Type is CAA cluste then TSOIRT & GSPORT will be "0"
   if (@attr_vals[$domaintype_index - 1] == $Domain_Type_CAA){
      @attr_vals[$tsport_index - 1] = "0";
      @attr_vals[$gsport_index - 1] = "0";

      $line = join($DELIMITER , @attr_vals);
   }

   # limit the output if -o or -O was specified
   if ($Opt_Only_Online || $Opt_Only_NotOnline) {
      if ($Opt_Only_Online && ($attr_vals[$opstate_index-1] == $RMC_OPSTATE_ONLINE)) {
         push (@lsr_out,$line);
      }
      if ($Opt_Only_NotOnline && ($attr_vals[$opstate_index-1] != $RMC_OPSTATE_ONLINE)) {
         push (@lsr_out,$line);
      }
   }
   else {
         push (@lsr_out,$line);
   }
}

# form 2D array to pass to display utils

# get heading from message file
@heading = getIMsg("IMsglsrpdomainHeading");

# form heading
@attr_names = split(/::/,$heading[0]);
$i = 1;
foreach $attr_name (@attr_names) {
   $lof_clusters[0][$i] = $attr_name;
   $i++;
} 

# get from message file what to use for no/yes 
@noyestext = getIMsg("IMsglsrpdomainNoYes");
@noyestext = split(/::/,$noyestext[0]);


# get from message file what to use for opstates
@opstatetext = getIMsg("IMsglsrpdomainOpState");
@opstatetext = split(/::/,$opstatetext[0]);

# fill in the hash for opstates
for ($op_cnt=0;$op_cnt<=$#opstatetext;$op_cnt=$op_cnt+2) {
   $op_states{$opstatetext[$op_cnt]} = $opstatetext[$op_cnt+1];
}

# form each line of output
$i = 1;
foreach $line (@lsr_out) {
   chomp($line);

   # parse the output
   @attr_vals = split(/$DELIMITER/, $line);

   # put into array
#  $lof_clusters[$i][0] = "\ncluster $i:";
   $lof_clusters[$i][0] = " ";
   $j = 1;
   foreach $attr_val (@attr_vals) {
      # translate opstate
      if ($j == $opstate_index) {
          $attr_val = lookup_opstate($attr_val,%op_states);
      }
      # translate mixed versions
      if ($j == $mixedvers_index) {
          $attr_val = lookup_yesno($attr_val,@noyestext);
      }
      # translate refresh interval
      if ($j == $refresh_index) {
          if ($attr_val == -1) {$attr_val = 0;}
          $attr_val = &calc_refresh($attr_val);
      }
     
      # put output into the output array 
      $lof_clusters[$i][$j] = $attr_val;
      $j++;
   }
   $i++;
}

# set how many rows of data there is
$row_count = $#lof_clusters; 
$col_count = scalar(@{$lof_clusters[0]});

# set formatting string needed by set_display
($Opt_Long_Format)  && ($display_type = "long");
($Opt_Table_Format) && ($display_type = "column");
($Opt_Delm_Format)  && ($display_type = "delim");

# print out results, if any
if ($row_count > 0) {
   $rc = set_display($display_type, $Opt_No_HDR, $row_count, $col_count,
                     \@lof_clusters, $Opt_Delm_Str);
}

if ($Verbose) { printIMsg("IMsglsrpdomainEnd"); }

if ($config_rc == 0) { exit($rc); }
else { exit($config_rc); } 

#--------------------------------------------------------------------#
# End Main Code                                                      #
#--------------------------------------------------------------------#


#--------------------------------------------------------------------#
# parse_cmd_line - Parse the command line for options and operands.  #
#   Set appropriate global variables as outlined below, make sure we #
#   have a valid combination of arguments / options.                 #
#                                                                    #
# Return:                                                            #
#   $rc   0                  Command line parsed fine, no problem.   #
#         CRM_CLI_BAD_FLAG   Command line contained a bad flag.      #
#   $cluster_name            Name of cluster to list.                #
#                                                                    #
# Global Variables Modified:                                         #
#   $Verbose           output   True (-V) turn Verbose mode on.      #
#   $Trace             output   True (-T) turn Trace mode on.        #
#   $Opt_Delm_Format   output   True (-d,-D) delimited output        #
#   $Opt_Delm_Str      output   char (-D) delimiter character        #
#   $Opt_Long_Format   output   True (-l) long formatted output      #
#   $Opt_Table_Format  output   True (-t) tabular formatted output   #
#   $Opt_No_HDR        output   True (-x) supress heading            #
#   $Opt_Only_Online   output   True (-o) list only online cluster   #      
#   $Opt_Only_NotOnline output  True (-O) list clusters not online   #
#--------------------------------------------------------------------#
sub parse_cmd_line 
{
my(@original_argv) = @ARGV;
my $cluster_name = "";                  # cluster name    
my %opts = ();

# Process the command line...
if (!&getopts('hoOltdD:xVT', \%opts)) { # Gather options; 
                                        # if errors
    &print_usage;                       # display proper usage
    return CRM_CLI_BAD_FLAG;            # return bad rc - bad flag 
}

# process h flag
if (defined $opts{h}) {                 # -h, help request
    &print_usage;                       # print usage statement
    exit(0);                            # all done with good return!
}

if (defined $opts{T}) {                 # -T turn trace on
    $Trace = $TRUE;
}

if (defined $opts{V}) {                 # -V turn verbose mode on
    $Verbose = $TRUE;
}

if (defined $opts{o}) {                 # -o for online cluster only
    $Opt_Only_Online = $TRUE;
}

if (defined $opts{O}) {                 # -O for not online clusters
                                        #    only
    if ($Opt_Only_Online) {             # -o already specified
       printCEMsg("EMsgConfigRMcliImproperUsageCombination","-o","-O");
       &print_usage;
       exit(CRM_CLI_BAD_FLAG);
    }
    $Opt_Only_NotOnline = $TRUE;
}

if (defined $opts{D}) {                 # -D delimited output with specified
    $Opt_Delm_Format = $TRUE;           #    delimiter
    $Opt_Delm_Str = $opts{D};
    $Opt_Long_Format = $FALSE;
}

if (defined $opts{d}) {                 # -d delimited output
    $Opt_Delm_Format = $TRUE;
    $Opt_Delm_Str = ":";
    $Opt_Long_Format = $FALSE;
}

if (defined $opts{t}) {                 # -t table formatted output
    $Opt_Table_Format = $TRUE;
    $Opt_Long_Format = $FALSE;
    $Opt_Delm_Format = $FALSE;
}

if (defined $opts{l}) {                 # -l long formatted output
    $Opt_Long_Format = $TRUE;
    $Opt_Table_Format = $FALSE;
    $Opt_Delm_Format = $FALSE;
}

if (defined $opts{x}) {                 # -x supress headings
    $Opt_No_HDR = $TRUE;
}

# Get the arguments...
# Operands:  cluster name
if ($#ARGV <= 0) {                      # cluster name and maybe more
   if ($#ARGV == 0) {
      $cluster_name = shift @ARGV;      # get cluster name
   }
}

else {            
    # cluster name not specified or too many
    printCEMsg("EMsgConfigRMcliInvalidNumberOfOperands");
    &print_usage;
    return CRM_CLI_BAD_OPERAND;
}

return(0, $cluster_name);               # success

}   # end parse_cmd_line


#--------------------------------------------------------------------#
# calc_refresh - Takes the CSSKRefreshInterval which is in seconds   #
#   and converts it to days:hours:minutes:seconds format.            #
#                                                                    #
# Input:                                                             #
#   $seconds                 The seconds value to be converted.      #
# Return:                                                            #
#   $formatted_refresh       The formatted refresh value in          #
#                            days:hours:minutes:seconds format.      #
#--------------------------------------------------------------------#
sub calc_refresh
{
my $seconds = @_;
my $d = 0;
my $h = 0;
my $m = 0;
my $s = 0;

my $formatted_refresh = "";

# calculate days (seconds/ (24*60*60) )
$d = int $seconds/86400;
$seconds = $seconds - ($d*86400);

# calculate hours (seconds/ (60*60) )
$h = int $seconds/3600;
$seconds = $seconds - ($h*3600);

# calculate minutes (seconds/60)
$m = int $seconds/60;

# calculate seconds
$s = $seconds - ($m*60);

# format result
$formatted_refresh = $d.":".$h.":".$m.":".$s;

return($formatted_refresh);

}   # end calc_refresh

#--------------------------------------------------------------------#
# print_usage : print the usage statement (syntax) to stdout.        #
#--------------------------------------------------------------------#
sub print_usage
{
&printIMsg("IMsglsrpdomainUsage");
}   # end print_usage