#!/usr/bin/perl
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 2000,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 = "@(#)05   1.28   src/rsct/rmc/cli/bin/lsactdef.perl, rmccli, rsct_rady, rady2035a 11/12/15 16:30:45"
######################################################################
#                                                                    #
# Module: lsactdef                                                   #
#                                                                    #
# Purpose:                                                           #
#   lsactdef - Lists (displays) action definitions of a resource     #
#              or resource class.                                    #
#                                                                    #
# Syntax:                                                            #
#   lsactdef [-h] [-c] [-p Property] [-s i|o] [-e] [-v]              #
#            [-l|-i|-t|-d|-D Delimiter] [-x] [-T] [-V]               #
#            [Resource_class [Action...]]                            #
#                                                                    #
# Flags:                                                             #
#   -h      Help. Writes this command's usage statement to stdout.   #
#   -c      Class. Displays the resource class action definitions.   #
#           By default the resource action definitions are displayed.#
#   -p Property Displays actions with the specified Property. By     #
#           default, only the definitions for public actions are     #
#           displayed. To display all action definitions regardless  #
#           of the action property, use the -p 0 flag. Refer to      #
#           ct_mc.h for action properties. An or-ing of the          #
#           properties will be accepted to display any action        #
#           definition that has at least one of the specified        #
#           properties.                                              #
#   -s      Displays the structured data definition for the action   #
#           input or action response.                                #
#           i - Display the action input SD definitions. This is     #
#               the default.                                         #
#           o - Display the action response (output) SD definitions. #
#   -e      Expands the descriptions. By default the definitions are #
#           displayed without the textual descriptions because they  #
#           can be lengthy. Specify this flag to see both the        #
#           definitions and descriptions.                            #
#   -v      Display action input valid values. Since only valid      #
#           values for action inputs are displayed, the -si flag     #
#           must be given in conjunction with the -v flag in order   #
#           to view valid values (if present).                       #
#   -l      Long formatted output. One entry per line. This is the   #
#           default display format. If the lsactdef command is       #
#           issued with the -l flag, but without a resource class    #
#           name, the -l flag is ignored when the command returns    #
#           the list of defined resource class names.                #
#   -i      Input format. Generates a template of the Resource Data  #
#           Input File. The output is displayed in long (stanza)     #
#           format. Which after appropriate editing can be used as   #
#           input to the runact command. The attribute's SD element  #
#           data types are displayed as the value in the Attr=value  #
#           pairs. It is suggested that when you use this flag, the  #
#           output of the lsactdef command be directed to a file.    #
#           The -i flag overrieds the -v flag.                       #
#   -t      Tabular formatted output. Each attribute is displayed    #
#           in a separate column one resource per line.              #
#   -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 a delimiter 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      Exclude 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 this command's verbose messages to       #
#           standard out.                                            #
#                                                                    #
# Operands:                                                          #
#   Resource_class  Resource class name. The name of the resource    #
#                   class whose action definitions you wish          #
#                   displayed. If no Resource_class operand is       #
#                   specified, a list of all the resource class      #
#                   names is displayed.                              #
#                                                                    #
#   Action          If a Resource_class operand is specified, zero   #
#                   or more action names may be specified. If no     #
#                   Action operand is specified, the definitions for #
#                   all the actions for the Resource_class are       #
#                   listed. Specific Action names may be entered     #
#                   to control which attributes are displayed and in #
#                   what order. Actions must be separated by spaces. #
#                                                                    #
# Description:                                                       #
#   The lsactdef command lists the action definitions of a resource  #
#   or resource class. Use lsactdef with no operands specified to    #
#   get a list of all resource class names.                          #
#                                                                    #
#   By default, the Resource action definitions are displayed. To    #
#   see the resource class action definitions, specify the -c flag.  #
#                                                                    #
#   By default, when no actions are specified on the command line,   #
#   only actions that are defined as public are displayed. To        #
#   override this default, use the -p flag or specify on the command #
#   line the names of the actions whose definition you wish to       #
#   display.                                                         #
#                                                                    #
#   To see the structured data definition that is required as input  #
#   when this action is invoked, specify the -s i flag. To see the   #
#   structured data definition linked with the output that results   #
#   from invoking this action, specify the -s o flag.                #
#                                                                    #
#   By default, for the actions that contain descriptions, the       #
#   descriptions are not displayed. Specify the -e flag to display   #
#   the descriptions. Because the translation of these descriptions  #
#   may take some time and because some of the descriptions are very #
#   long, the default is not to display these descriptions. If       #
#   descriptions for members of the valid_vals list are available,   #
#   they are displayed with the -e flag as well.                     #
#                                                                    #
#   By default, for action inputs that have defined valid values, the#
#   valid values are not displayed.  Specify the -v and -si flags to #
#   view the valid values of action input structured data elements.  #
#   Because valid values are not returned as part of the base action #
#   definition of the resource or resource class, and extra calls to #
#   RMC must be made to retrieve the valid values, the default is    #
#   not to display them. Valid_vals and valid_vals_label fields are  #
#   blank for pointer data types.                                    #
#                                                                    # 
#                                                                    #
# Exit Values:                                                       #
#   0  MC_CLI_SUCCESS        Command completed successfully.         #
#   1  MC_CLI_RMC_ERROR      Command terminated due to an underlying #
#                            RMC error.                              #
#   2  MC_CLI_ERROR          Command terminated due to an underlying #
#                            error in the command script.            #
#   3  MC_CLI_BAD_FLAG       Command terminated due to user          #
#                            specifying an invalid flag.             #
#   4  MC_CLI_BAD_OPERAND    Command terminated due to user          #
#                            specifying a bad operand.               #
#   5  MC_CLI_USER_ERROR     Command terminated due to a user error. #
#                            For example specifying an undefined     #
#                            Resource name as the Resource operand.  #
#                                                                    #
# Examples:                                                          #
#   lsactdef                     (lists all resource class names     #
#   lsactdef IBM.Foo             (lists resource actions definitions)#
#   lsactdef -c IBM.Foo          (lists resouce class actions defs)  #
#   lsactdef -s i -t IBM.Foo     (lists resource actions input SD)   #
#   lsactdef -e IBM.Foo          (lists rsrc actions def with desc)  #
#   lsactdef -s o IBM.Foo ExecuteCommand (lists resource action      #
#                                 response SD for ExecuteCommand     #
#                                 action for IBM.Foo                 #
#   lsactdef -i IBM.Foo          (lists template of action inputs    #
#                                 to use as input to runact command  #
#   lsactdef -v -si -IBM.Foo     (lists resource action input SDs    #
#                                 along with valid values, if present#
#                                                                    #
# Man Page:                                                          #
#   For the most current detailed description of this command see    #
#   the lsactdef man page in /opt/rsct/man.                     #
#                                                                    #
#--------------------------------------------------------------------#
# Inputs:                                                            #
#   /opt/rsct/msgmaps/mccli.lsactdef.map - message mapping      #
#   /opt/rsct/msgmaps/mccli.mccli.map - message mapping         #
#                                                                    #
# Outputs:                                                           #
#   stdout - display of the resource action definitions.             #
#   stderr - any error message.                                      #
#                                                                    #
# External Ref:                                                      #
#   Commands: ctdspmsg                                               #
#   Modules:  MC_cli_utils.pm, MC_cli_display_utils.pm, MC_cli_rc.pm #
#             CT_cli_utils.pm, CT_cli_data_type_utils                #
#   Extensions:  CT::MC, CT::MCerr, CT::CT                           #
#   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:                                                   #
#   000512 SAB 64351: Initial design & write.                        #
#   010311 SAB 63852: Prepared for GA.                               #
#   010806 YSK 75111: Added -v, valid values support.                #
#   020307 JAC 80687: Remove -v and go back to old usage.            #
#   021220 JAC 88088: Use rmc api commands instead of extension.     #
#   030709 JAC 96745: Add delimiter to call to remove_api_error.     #
#   080122 JAC 145056: translate "action" title.                     #
######################################################################

#--------------------------------------------------------------------#
# General Program Flow/Logic:                                        #
#                                                                    #
# A. Parse command line flags and operands, determine which flavor   #
#    of this command we are actually invoking.                       #
#    This command allows a user to see the Action definitions for    #
#    the specified resource class.                                   #
#    They can select to see one of:                                  #
#       * Names of all defined resource classes on this system.      #
#       * The Resource Class Action Definitions                      #
#       * The Resource Class Action Input Definitions                #
#       * The Resource Class Action Response Definitions             #
#       * The Resource Action Definitions                            #
#       * The Resource Action Input Definitions                      #
#       * The Resource Action Response Definitions                   #
#       * Resource Data Input File format for runact command.        #
# B. Initialize a session with RMC.                                  #
# C. Query the definition of the SD or Action using RMC.             #
# D. Display the requested definitions in the appropriate format.    #
# E. Cleanup.                                                        #
#--------------------------------------------------------------------#

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

use autouse CT_cli_utils => qw(
    printIMsg
    printEMsg
);

use MC_cli_rc qw(:return_codes);
use autouse MC_cli_utils => qw(
    build_HoAttr
    qdef_resource_class
    error_exit
    process_exit_code
    process_api_error
    remove_api_error
    printCEMsg
);
use autouse MC_cli_display_utils => qw(
    display_resource_data_api
    display_resource_data_api2
    convert_sd_valid_values
    convert_sd_valid_values_label
    getIMsg
);


#--------------------------------------------------------------------#
# Global Variables                                                   #
#--------------------------------------------------------------------#
$TRUE = 1;
$FALSE = 0;

$Verbose = $FALSE;                      # default - verbose turned off

# By default output is written in long format.
$Opt_Long_Format = $TRUE;               # default - see -l (long form)
$Opt_Table_Format = $FALSE;             # default - see -t (table)
$Opt_Delm_Format = $FALSE;              # default - see -d (delimiter)
$Opt_Delm_Str = ":";                    # default - see -D (colon :) 
$Opt_No_HDR = $FALSE;                   # default - see -x
$Opt_Exp_Desc = $FALSE;                 # default - see -e
$Opt_LS_Class = $FALSE;                 # default - see -c
$Opt_LS_Input_File = $FALSE;            # default - see -i
$Opt_LS_SD = $FALSE;                    # default - see -s 
$Opt_SD_Input = $FALSE;                 # default - see -s i
$Opt_Valid_Vals = $FALSE;               # default - see -v 

$PROGNAME = "lsactdef";                 # Program Name for messages
$MSGCAT = "mccli.cat";                  # msg catalogue for this cmd

$CTDIR = "/opt/rsct";              # RSCT root directory
$CTBINDIR = "$CTDIR/bin";               # Cluster Bin directory path
$LSMSG = "$CTBINDIR/ctdspmsg";          # display message rtn.
$ENV{'MSGMAPPATH'} = "$CTDIR/msgmaps";  # msg maps used by $LSMSG

#--------------------------------------------------------------------#
# Variables                                                          #
#--------------------------------------------------------------------#
@LoSDAttr = ();
%HoSDDefs = ();
@LoActions = ();
%HoActions = ();
$rc = 0;
$rc2 = 0;
$DELIMITER = "tvrtvrtvr";
@lsr_out = ();
@lsr_out2 = ();
$j = 0;
@attributes = ();
@rresponse = ();

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

# Parse the command line, exit if there are errors 
my ($rc, $resource, $req_properties, @actions) = &parse_cmd_line;
($rc == 0) || exit($rc);

# set the quote string environment variable, if necessary
if (!defined $ENV{CT_CLI_QUOTE_STRING}){
   $ENV{CT_CLI_QUOTE_STRING} = 1;
}

# If no resource names were specified as an operand to this command
# display the list of all resource names.
if (!$resource) {               # No resource operand

    # List the Resource Class Names
    # call lsrsrcdef-api to get the list of classes
    if ($Trace) { print STDERR "$PROGNAME: calling lsrsrcdef-api\n";}

    @lsr_out = `$CTBINDIR/lsrsrcdef-api -I $DELIMITER -D $DELIMITER -c "*" 2>&1`;

    # capture the return code from lsrsrcdef-api
    $rc = $?;
    $rc = process_exit_code($rc);

    if ($Trace) { print STDERR "lsrsrcdef-api results:\n";
              print STDERR "@lsr_out";
              print STDERR "$PROGNAME: lsrsrcdef-api returned $rc\n";}

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

    # remove any error messages from the output to display
    @lsr_out = remove_api_error($DELIMITER,@lsr_out);

    # extract only the class names
    for ($j=0;$j<=$#lsr_out;$j=$j+2) {
       @temp_line = split(/$DELIMITER/, $lsr_out[$j]);
       push @lsr_out2, $temp_line[0];
    }

    # save the attribute name to display
    push @LoPAttr, "class_name";

     # use table output format
    $Opt_Table_Format = $TRUE;
    $Opt_Long_Format = $FALSE;
    $Opt_LS_DAttr = $FALSE;
    $Opt_LS_PAttr = $FALSE;

    my $row_title = "resource";

    # check for delimited output
    if ($Opt_Delm_Format) { $Opt_Table_Format = $FALSE; }

    # print output if lsrsrcdef-api command worked or there's
    # something to print
    if ($rc ==0 || $#lsr_out2 >=0 )
       {
          # Display the Resource Class Persistent Attributes
          $rc2 = display_attributes_api("", $row_title, \@attributes, \@LoPAttr, \@lsr_out2);
          if ($rc == 0) { $rc = $rc2; }
       }

    ($rc == 0) || exit($rc);

}

# Create an Input file template suitable for input to runact
# Only 1 action name can be specified.
elsif ($Opt_LS_Input_File) {
    # Select the actions that have at least one of the requested
    # properties or were in the list of actions specified on the
    # command line (action operands override -p flag).
    $rc = select_actions($resource, $req_properties, \@actions);
    ($rc == 0) || exit($rc);

    $rc = qdef_sd($resource, \@actions, \@rresponse);
    ($rc == 0) || exit($rc);

    # Format the Resource or Resource Class SD Actions Definition 
    # into a form suitable for display. There may be 0 or more SDs.
    format_sd_defs_for_input($resource, \@rresponse, \@actions, 
        \%HoSDDefs);

    # Display the Resource or Resource Class Action SD elements 
    # in a format suitable for input to runact (once real values
    # are substituted into the attr=value pairs).
    $rc = display_sd_for_input(\@actions, \%HoSDDefs);
    ($rc == 0) || exit($rc);
}

elsif ($Opt_LS_SD) {
    # Select the actions that have at least one of the requested
    # properties or were in the list of actions specified on the
    # command line (action operands override -p flag).
    $rc = select_actions($resource, $req_properties, \@actions);
    ($rc == 0) || exit($rc);

    # If there are any SD action definitions that should be 
    # displayed (there action has appropriate property) 
    # let the subroutine make the call to the extension, and 
    # handle all the assorted potential errors.
    if (scalar(@actions) > 0) {
        $rc = qdef_sd($resource, \@actions, \@rresponse);
        ($rc == 0) || exit($rc);

        # Get response for valid values if they were requested by user.
        # Call subroutine to handle valid values extension.
        #if ($Opt_Valid_Vals && $Opt_SD_Input) {
        #    my $usage = $Opt_LS_Class ? MC_VV_USAGE_CLASS_ACTION_INPUT
        #                              : MC_VV_USAGE_RSRC_ACTION_INPUT;

        #    $response_vv = CT::MC::qdef_valid_vals_rsp_t->new;
        #    $rc = qdef_valid_vals($session, $resource, \@actions,
        #        $response_vv, $usage);
        #    ($rc == 0) || error_exit($rc);
        #}

        # Format the Resource or Resource Class SD Actions Definition 
        # into a form suitable for display. There may be 0 or more SDs.
        format_sd_defs($resource, \@rresponse, \@actions,
            \@LoSDAttr, \%HoSDDefs, $response_vv);
    }

    # Display the Resource or Resource Class Actions Defs & Desc
    $rc = display_sd_defs($resource, \@actions, \@LoSDAttr, 
        \%HoSDDefs);
    ($rc == 0) || exit($rc);
}

else {
    # list the actions of the class (or only the one(s) specified)
    $rc = qdef_actions($resource, $Opt_LS_Class, \@actions, \@rresponse);
    ($rc == 0) || exit($rc);

    # Format the Query Definition Actions for a Resource into
    # a form suitable for display.  
    format_actions($resource, \@rresponse, $req_properties, \@actions, 
                   \@LoActions, \%HoActions);

    # Display the Resource Actions Defs & Desc
    @actions = ();
    $rc = display_actions(\@actions, \@LoActions, \%HoActions); 
    ($rc == 0) || exit($rc);
}

exit $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.   #
#         SR_CLI_BAD_FLAG    Command line contained a bad flag.      #
#   $resource                Resource Class Name.                    #
#   $properties              Attributes having these properties      #
#                            should be displayed.                    #
#   @actions                 Array of action names.                  #
#                                                                    #
# Global Variables Modified:                                         #
#   $Opt_Current       output   True (-c) print current cluster info #
#   $Opt_Exp_Desc      output   True (-e) print both definition      #
#                               and description (print all).         #
#   $Opt_LS_Class      output   True (-c) display the class resource #
#                               def vs just the resource def.        #
#   $Opt_LS_Input_File output   True (-i) create/list an input file  #
#                               suitable for runact.                 #
#   $Opt_LS_SD         output   True (-s) display the detailed       #
#                               structured data definition for a     #
#                               attr defined as an SD.               #
#   $Opt_SD_Input      output   True (-s i) display the input action #
#                               SDs, -s o dislplay the output action #
#                               SDs (response SDs).                  #
#   $Opt_Valid_Vals    output   True (-v) display valid values.      #
#   $Opt_Long_Format   output   True (-l) print one entry per line   #
#   $Opt_Table_Format  output   True (-t) table format.              #
#   $Opt_Delm_Format   output   True (-d|-D) print delimiter         #
#                               separated output.                    #
#   $Opt_Delm_Str      output   the string to use as the delimiter,  #
#                               default is colon (:).                #
#   $Opt_No_HDR        output   True (-x) print without header       #
#   $Verbose           output   True (-V) turn Verbose mode on.      #
#   $Trace             output   True (-T) turn Trace mode on.        #
#--------------------------------------------------------------------#
sub parse_cmd_line 
{
my(@original_argv) = @ARGV;
my $resource = "";
my @actions = ();
my %opts = (); 

# Process the command line...
#if (!&getopts('hceip:s:dD:ltxvVT',\%opts)) { # Get options; if errors
if (!&getopts('hceip:s:dD:ltxVT',\%opts)) { # Get options; if errors
    &print_usage;                       # display proper usage
    return MC_CLI_BAD_FLAG;             # return bad rc - bad flag 
}

# Always accept the -h help flag regardless of other flags or operands
if (defined $opts{h}) {                 # -h, help request  
    &print_usage;                       # print usage statement
    exit(0);                            # all done with good return!
}

# If no operands in lsactdef that is OK, it just means display
# a list of all Resource Class Names

# Get the arguments...
if ($#ARGV >= 0) { 
    $resource = shift @ARGV;            # user specified resource
    @actions = @ARGV;                   # array of action names
}

# See which options/flags were used...

if (defined $opts{c}) {                 # -c, rsrc class definitions
    $Opt_LS_Class = $TRUE;
}

if (defined $opts{e}) {                 # -e, display all desc & def
    $Opt_Exp_Desc = $TRUE;
}

# -i overrides -s  (only action input used for runact)
if (defined $opts{i}) {
    $Opt_LS_Input_File = $TRUE;
    $Opt_SD_Input = $TRUE;
}
elsif (defined $opts{s}) {                 # -s, sd definitions  
    $Opt_LS_SD = $TRUE;
    if ($opts{s} eq "i") {              # qdef SD action input
        $Opt_SD_Input = $TRUE;
    }
    elsif ($opts{s} eq "o") {           # qdef SD action response
        $Opt_SD_Input = $FALSE;
    }
    else {
        # -s flag requires i input | o output (response)
        printCEMsg("EMsgMCcliImproperUsageFlag", "-s $opts{s}");   
        &print_usage;
        return(MC_CLI_BAD_FLAG, $resource); 
    }
}

# The -v flag is overriden by -i and req's -si
if (defined $opts{v}
    && !defined $opts{i}
    && $Opt_SD_Input) {
    $Opt_Valid_Vals = $TRUE;
}

if (defined $opts{p}) {                 # -p Property
    $properties = $opts{p};
    # Make sure properties is a number (hex, octal or decimal)
    if ($properties !~ /^(0x|\d+)\d*/) {
        printCEMsg("EMsgMCcliImproperUsageFlag", "-p $opts{p}");
        return MC_CLI_USER_ERROR;
    }
    # Convert properties specified in hex or octal to decimal
    $properties = oct $properties if $properties =~ /^0/;

    # Just some mininmal range checking - valid property values only
    # range between 0x0001 to 0x0020 but allow for growth here
    # -p 0 means display actions with any property
    if ($properties < hex("0x0000") || $properties > hex("0xFFFF")) {
        printCEMsg("EMsgMCcliImproperUsageFlag", "-p $opts{p}");
        return MC_CLI_USER_ERROR;
    }
    if ($properties == 0) {
        $properties = hex("0xFFFF");
    }
}
else {
    # Default to display only public actions
    $properties = hex("0x0002");          # Default to Public property
}


# The -l flag overrides -t which overrides -d which overrides -D flag
# When -i flag used always display in long format
if (defined $opts{l} || defined $opts{i}) { # -l long format,
    $Opt_Long_Format = $TRUE;          #    1 entry per line  
}
elsif (defined $opts{t}) {             # -t tabular format
    $Opt_Table_Format = $TRUE;
    $Opt_Long_Format = $FALSE;
}
elsif (defined $opts{d}) {             # -d delimiter format
    $Opt_Delm_Format = $TRUE;
    $Opt_Long_Format = $FALSE;
}
elsif (defined $opts{D}) {             # -D <delimiter> format
    $Opt_Delm_Format = $TRUE;
    $Opt_Long_Format = $FALSE;
    $Opt_Delm_Str = $opts{D};
}

if (defined $opts{x}) {                # -x do not print header
    $Opt_No_HDR = $TRUE;
}

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

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

return(0, $resource, $properties, @actions); # success
}   # end parse_cmd_line


#--------------------------------------------------------------------#
# print_usage - print the usage statement (syntax) to stdout.        #
#   See this command's prologue syntax section for current usage.    #
#--------------------------------------------------------------------#
sub print_usage
{
printIMsg("IMsglsactdefUsage");
}   # end usage


#--------------------------------------------------------------------#
# qdef_actions - function to call lsrsrcdef-api to list the actions  #
#   of a class.                                                      #
#                                                                    #
# Parameters:                                                        #
#   $resource         input   Name of the resource class whose       #
#                             action definition we want.             #
#   $query_class_actions in   1 - query resource class actions.      #
#                             0 - query resource actions.            #
#   @$r_actions       input   Reference to array of action names.    #
#   @$response        in/out  Reference to a list containing the     #
#                             result of the lsrsrcdef-api call.      #
#                                                                    #
# Return:                                                            #
#   $rc                       return code.                           #
#                                                                    #
# Global References:                                                 #
#   $Opt_Exp_Desc     input  TRUE if display def & description.      #
#   $Opt_LS_Class     input  TRUE if display resource class def      #
#                            versus the resource def.                #
#--------------------------------------------------------------------#
sub qdef_actions
{
my ($resource, $query_class_actions, $r_actions, $response) = @_;
my $rc = 0;
my @lsr_out = ();
my $cmd_flg = "";
my $action_count = scalar(@$r_actions);

my $action_list = "";
my $action_name = "";

# see if descriptions are required
if ($Opt_Exp_Desc) { $cmd_flg = "-q";}

# decide which actions to list, class or resource
if ($query_class_actions) { $cmd_flg .= " -A";}
else { $cmd_flg .= " -a";}

# build action list for lsrsrcdef-api
if ($#$r_actions >= 0) {
   foreach $action_name (@$r_actions) {
      $action_list .= $DELIMITER . $action_name;
   }
}

# call lsrsrcdef-api to get the action information
if ($Trace) { print STDERR "$PROGNAME: calling lsrsrcdef-api\n";}

@lsr_out = `$CTBINDIR/lsrsrcdef-api -I $DELIMITER -D $DELIMITER $cmd_flg "${resource}${action_list}" 2>&1`;

# capture the return code from lsrsrcdef-api
$rc = $?;
$rc = process_exit_code($rc);

if ($Trace) { print STDERR "lsrsrcdef-api results:\n";
          print STDERR "@lsr_out";
          print STDERR "$PROGNAME: lsrsrcdef-api returned $rc\n";}

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

# remove any error messages from the output to display
@lsr_out = remove_api_error($DELIMITER,@lsr_out);

@$response = @lsr_out;

return $rc;
}   # end qdef_actions


#--------------------------------------------------------------------#
# qdef_sd - function to call lsrsrcdef-api to get input/response     #
#   information.                                                     #
#                                                                    #
# Parameters:                                                        #
#   $resource         input   Name of the resource class whose SD    #
#                             definition we want.                    #
#   @$r_actions       input   Reference to array of action names.    #
#   @$response        in/out  Reference to list of information       #
#                             returned from lsrsrcdef-api.           #
#                                                                    #
# Return:                                                            #
#   $rc                       return code.                           #
#                                                                    #
# Global References:                                                 #
#   $Opt_Exp_Desc     input   TRUE if display def & description.     #
#   $Opt_LS_Class     input   TRUE if display resource class def     #
#                             versus the resource def.               #
#   $Opt_SD_Input     input   TRUE if display action input SDs.      #
#                             FALSE if display action response SDs.  #
#--------------------------------------------------------------------#
sub qdef_sd
{
my ($resource, $r_actions, $response) = @_;
my $rc = 0;
my @lsr_out = ();
my $cmd_flg = "";
my $action_list = "";
my $action_name = "";
 
# see if descriptions are required
if ($Opt_Exp_Desc) { $cmd_flg = "-q";}

# decide which actions to list, 
# class or resource, and input or response
# listing the class, check input vs response
if ($Opt_LS_Class) {
    if ($Opt_SD_Input) { $cmd_flg .= " -X";}
    else { $cmd_flg .= " -Y";}
}
# listing the resource, check input vs response
else {
    if ($Opt_SD_Input) { $cmd_flg .= " -x";}
    else { $cmd_flg .= " -y";}
}

my $action_count = scalar(@$r_actions);

# build action list for lsrsrcdef-api
if ($#$r_actions >= 0) {
   foreach $action_name (@$r_actions) {
      $action_list .= $DELIMITER . $action_name;
   }
}

# call lsrsrcdef-api to get the action information
if ($Trace) { print STDERR "$PROGNAME: calling lsrsrcdef-api\n";}

@lsr_out = `$CTBINDIR/lsrsrcdef-api -I $DELIMITER -D $DELIMITER $cmd_flg "${resource}${action_list}" 2>&1`;

# capture the return code from lsrsrcdef-api
$rc = $?;
$rc = process_exit_code($rc);

if ($Trace) { print STDERR "lsrsrcdef-api results:\n";
          print STDERR "@lsr_out";
          print STDERR "$PROGNAME: lsrsrcdef-api returned $rc\n";}

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

# remove any error messages from the output to display
@lsr_out = remove_api_error($DELIMITER,@lsr_out);

@$response = @lsr_out;

return $rc;
}   # end qdef_sd


#--------------------------------------------------------------------#
# select_actions - Returns a list of action names that have at least #
#   one of the requested properties or was specified as the action   #
#   operand on the command line. Action operands override -p flag.   #
#                                                                    #
# Parameters:                                                        #
#   $resource         input   Name of the resource class whose       #
#                             action definitions we want.            #
#   $req_properties   input   Return actions with at least one of    #
#                             these properties.                      #
#   @$r_actions       in/out  Reference to list of action names.     #
#                             On input actions from command line     #
#                             (if any).                              #
#                             On output filtered list of act names.  #
#                                                                    #
# Return:                                                            #
#   $rc                       return code.                           #
#                                                                    #
# Global References:                                                 #
#   $Opt_LS_Class     input   TRUE if display resource class def     #
#                             versus the resource def.               #
#--------------------------------------------------------------------#
sub select_actions {
my ($resource, $req_properties, $r_actions) = @_;

my @req_actions = ();
my @r_info = ();
my @actions = ();
my @loActions = ();
my $action_name;
my $action_prop;
my $prop;
my $rc = 0; 

# Get the actions info for the resource class
# (either resource actions or class actions
$rc = qdef_actions($resource, $Opt_LS_Class, \@actions, 
    \@loActions);
($rc == 0) || exit($rc);

my $response_cnt = $#loActions;
my $r;

# Build the action name list
for ($r = 0; $r <= $response_cnt; $r++) {

     # parse the action information
     chomp($loActions[$r]);
     @r_info = split (/$DELIMITER/, $loActions[$r]);

     # get the name and properties
     $action_name = $r_info[0];  
     $action_name =~ s/^\"//;
     $action_name =~ s/\"$//;
     $action_prop = $r_info[3];  

     # Filter out the actions that are not required 
     # Actions requested as operands to this command always get
     # displayed ($r_actions), otherwise display any action
     # that has at least one of the requested properties.
     #(required_attr($action_name, $actions->properties($a), 
     #    $r_actions, $req_properties)) || next;

     $prop = 0;
     if ( $action_prop =~ /long_running/) { $prop = $prop | 1;}
     if ( $action_prop =~ /public/)       { $prop = $prop | 2;}
     if ( ($req_properties & $prop) == 0  &&
          ($req_properties != hex("0xFFFF"))  )
             { next;}

     push @req_actions, $action_name;
}

if (scalar(@$r_actions) == 0) {
    foreach $action_name (@req_actions) {
        push @$r_actions, $action_name;
    }
}

return $rc;
}   # end select_actions


#--------------------------------------------------------------------#
# format_actions - formats the qdef actions into a complex hash of   #
#   attribute elements %rHoAttr which can then be easily displayed   #
#   using utility display_resource_data.                             #
#                                                                    #
# Parameters:                                                        #
#   $resource         input   Resource Name                          #
#   $response         input   lsrscdef-api output structure.         #
#   $req_properties   input   Filter out actions that do not have    #
#                             at least one of the specified required #
#                             properties. Actions specified on the   #
#                             comman line override this.             #
#   @$r_actions       input   If Empty format all the actions        #
#                             that have at least one of the required #
#                             properties otherwise only format       #
#                             actions in this list.                  #
#   @$rLoActions      in/out  Reference to the list of action names  #
#                             that are also in HoActions.            #
#   %$rHoActions      in/out  Reference to the hash of actions.      #
#                                                                    #
# Global References:                                                 #
#   None.                                                            #
#--------------------------------------------------------------------#
sub format_actions
{
my($resource, $response, $req_properties, $r_actions, 
    $rLoActions, $rHoActions) = @_;

my($r, $j);

# format each of the actions in the response structure so 
# can use more generic printing....
# permissions is commented out right now since RMC wasn't setting
# it.
my %HoRspAttr = ( 
    "action_name"       => 1,
    "display_name"      => 1,
    "description"       => 1,
    "properties"        => 1,
    "confirm_prompt"    => 1,
    "action_id"         => 1,
    "variety_list"      => 1,
    "variety_count"     => 1,
    "timeout"           => 1,
#   "permissions"       => 1,
);  

my %elements = ();
my @r_info = ();
my $response_cnt = $#$response;
my $i = 0;
my $prop = 0;

# go through the lsrsrcdef-api out and assign the values in order
for ($r = 0; $r <= $response_cnt; $r++) {

    chomp($$response[$r]);
    @r_info = split (/$DELIMITER/, $$response[$r]);

        # Filter out the actions that should not be displayed
        # Actions requested as operand to this command always get
        # displayed ($r_actions), otherwise display any action 
        # that has one of the requested properties.
        #(required_attr($actions->action_name($a), 
        #    $actions->properties($a), $r_actions, $req_properties)) ||
        #    next;
        $prop = 0;
        if ( $r_info[3] =~ /long_running/) { $prop = $prop | 1;}
        if ( $r_info[3] =~ /public/)       { $prop = $prop | 2;}
        if ( ($req_properties & $prop) == 0  &&
             ($req_properties != hex("0xFFFF"))  )
             { next;}

        if ($HoRspAttr{"action_name"}) {
            %elements = ();
            $elements{at_name} = "action_name";
            $elements{at_dtype} = "CT_CHAR_PTR";
            $elements{at_value} = $r_info[0];
            build_HoAttr($elements{at_name}, $rLoActions, $rHoActions,
                \%elements, $i);
        }

        if ($HoRspAttr{"display_name"}) {
            %elements = ();
            $elements{at_name} = "display_name";
            $elements{at_dtype} = "CT_CHAR_PTR"; 
            $elements{at_value} = $r_info[1];
            build_HoAttr($elements{at_name}, $rLoActions, $rHoActions,
                 \%elements, $i);
        }

        if ($HoRspAttr{"description"}) {
            %elements = ();
            $elements{at_name} = "description";
            $elements{at_dtype} = "CT_CHAR_PTR";
            $elements{at_value} = $r_info[2];
            build_HoAttr($elements{at_name}, $rLoActions, $rHoActions,
                 \%elements, $i);
         }

        if ($HoRspAttr{"properties"}) {
            %elements = ();
            $elements{at_name} = "properties";
            $elements{at_dtype} = "CT_CHAR_PTR_ARRAY";
            $elements{at_value} = $r_info[3];
            build_HoAttr($elements{at_name}, $rLoActions, $rHoActions,
                 \%elements, $i);
         }

        if ($HoRspAttr{"confirm_prompt"}) {
            %elements = ();
            $elements{at_name} = "confirm_prompt";
            $elements{at_dtype} = "CT_CHAR_PTR";
            $elements{at_value} = $r_info[4];
            build_HoAttr($elements{at_name}, $rLoActions, $rHoActions,
                \%elements, $i);
         }

        if ($HoRspAttr{"action_id"}) {
            %elements = ();
            $elements{at_name} = "action_id";
            $elements{at_dtype} = "CT_UINT32";    # Really a CT_UINT16
            $elements{at_value} = $r_info[5];
            build_HoAttr($elements{at_name}, $rLoActions, $rHoActions,
                 \%elements, $i);
        }

        if ($HoRspAttr{"variety_list"}) {
            %elements = ();
            $elements{at_name} = "variety_list";
            $elements{at_dtype} = "CT_SD_PTR_ARRAY";
            $elements{at_value} = $r_info[6];
            build_HoAttr($elements{at_name}, $rLoActions, $rHoActions,
                \%elements, $i);
         }

        if ($HoRspAttr{"variety_count"}) {
            %elements = ();
            $elements{at_name} = "variety_count";
            $elements{at_dtype} = "CT_UINT32";
            $elements{at_value} = $r_info[7];
            build_HoAttr($elements{at_name}, $rLoActions, $rHoActions,
                 \%elements, $i);
        }

        if ($HoRspAttr{"timeout"}) {
            %elements = ();
            $elements{at_name} = "timeout";
            $elements{at_dtype} = "CT_UINT32";
            $elements{at_value} = $r_info[8];
            build_HoAttr($elements{at_name}, $rLoActions, $rHoActions,
                 \%elements, $i);
        }

        # TODO: add permissions back in when they really get set
        # Permissions have not been set in this release
        # if ($HoRspAttr{"permissions"}) {
        #    %elements = ();
        #    $elements{at_name} = "permissions";
        #    $elements{at_dtype} = CT_UINT32;
        #    $elements{at_value} = $actions->permissions($a);
        #    build_HoAttr($elements{at_name}, $rLoActions, $rHoActions,
        #         \%elements, $i);
        # }
    
        $i = $i + 1;

}   # end for responses

return;
}   # end format_actions


#--------------------------------------------------------------------#
# format_sd_defs_for_input - formats the structured data definitions #
#   actions.  0 or more SDs may have been defined. A complex hash    #
#   is constructed -                                                 #
#      level 1:  Complex hash                                        #
#                key is action name (see mc_sd_rsp_t in ct_mc.h)     #
#                data hash of definition data for an SD.             #
#      level 2:  Complex hash                                        #
#                key is element name (see mc_sd_element_t in ct_mc.h)#
#                data value                                          #
#      x $rHoSDDefs - to really see what is created.                 #
#      x $$rHoSDDefs{$response->program_name($r)} to see level 2.    #
#      The hash for each action (level 2) can be easily displayed    #
#      using the MC_cli_display_utils::display_resource_data.        #
#                                                                    #
# Parameters:                                                        #
#   $resource         input   Resource Name                          #
#   $response         input   Reference to lsrsrcdef-api output.     #
#   @$r_actions       input   Reference to the list of actions       #
#                             to be displayed, if empty display all  #
#                             actions.                               #
#   %$rHoSDDefs       in/out  Reference to the hash of Action SD     #
#                             element definitions.                   #
#                                                                    #
# Global References:                                                 #
#   None.                                                            #
#--------------------------------------------------------------------#
sub format_sd_defs_for_input
{
my($resource, $response, $r_actions, $rHoSDDefs) = @_;
my @actions = ();
my @r_info = ();
my $response_cnt = $#$response;

# format each of the actions in the response structure so
# can use more generic printing....
my ($r, $e);
my @LoAttr = ();
my %HoAttr = ();
my %elements = ();
my $element_name = "";

for ($r = 0; $r <= $response_cnt; $r++) {
    chomp($$response[$r]);
    @r_info = split (/$DELIMITER/, $$response[$r]);

    $action_name = $r_info[0];
    $action_name =~ s/^\"//;
    $action_name =~ s/\"$//;

    # Building up hash of attr=value pairs where the attribute
    # is really an SD element name, value is the element data type

        # Filter out elements that have already been processed
        $element_name = $r_info[1];
        $element_name =~ s/^\"//;
        $element_name =~ s/\"$//;
        (exists $HoAttr{$element_name}) && next;
    
        %elements = ();
        $elements{at_name} = $element_name;
        $elements{at_dtype} = "CT_CHAR_PTR";
        $data_type = $r_info[2];
        $data_type =~ s/^CT_//;
        $data_type = lc $data_type;
        $elements{at_value} = "\"".$data_type."\"";
        #$elements{at_value} = $data_type;
        $elements{at_id} = $r_info[5];
        build_HoAttr($elements{at_name}, \@LoAttr, \%HoAttr,
            \%elements, 0);

    # at the end of this definition for this action?
    if ( ($r == $response_cnt) || ($$response[$r+1] =~ /${DELIMITER}0\n$/) ) {

        # Put this SD Attribute definition in the hash with the rest of
        # the SD attributes definitions.
        push @actions, $action_name;
        $$rHoSDDefs{$action_name} = { %HoAttr };
    }

    if ( ($r < $response_cnt) && ($$response[$r+1] =~ /${DELIMITER}0\n$/) ) {
        @LoAttr = ();
        %HoAttr = ();
    }
}   # end for each response

# If the action array isn't set then set it to the actions return 
# by RMC
if (scalar @$r_actions < 1 && scalar @actions > 0) {
    push @$r_actions, @actions;
}

return;
}   # end of format_sd_defs_for_input


#--------------------------------------------------------------------#
# format_sd_defs - formats the structured data definitions for       #
#   actions.  0 or more SDs may have been defined. A complex hash    #
#   is constructed -                                                 #
#      level 1:  Complex hash                                        #
#                key is action name (see mc_sd_rsp_t in ct_mc.h)     #
#                data hash of definition data for an SD.             #
#      level 2:  Complex hash                                        #
#                key is element_name (see mc_sd_element_t in ct_mc.h)#
#                data value                                          #
#      x $rHoSDDefs - to really see what is created.                 #
#      x $$rHoSDDefs{action-name} to see level 2.                    #
#      The hash for each action (level 2) can be easily displayed    #
#      using the MC_cli_display_utils::display_resource_data.        #
#                                                                    #
# Parameters:                                                        #
#   $resource         input   Resource Name                          #
#   @$response        input   Reference to lsrsrcdef-api output.     #
#   @$r_actions       input   Reference to the list of actions to be #
#                             displayed, empty display all actions.  #
#   @$rLoSDAttr       in/out  Reference to the list of SD attributes #
#                             (element fields) that are also in      #
#                             HoSDDefs.                              #
#   %$rHoSDDefs       in/out  Reference to the hash of Action SD     #
#                             element definitions.                   #
#   $response_vv      input   Valid values response structure.       #
#                                                                    #
# Global References:                                                 #
#   $Opt_Valid_Vals   input   TRUE if valid values are being         #
#                             displayed.                             #
#--------------------------------------------------------------------#
sub format_sd_defs
{
my($resource, $response, $r_actions, $rLoSDAttr, $rHoSDDefs, 
    $response_vv) = @_;

my @actions = ();
my $r;

# format each of the Action SDs in the response structure so
# can use more generic printing....

# Hash of field names in the qdef_sd_rsp_t (mc_sd_element_t)
my %HoRspAttr = (
    "element_name"          => 1,
    "display_name"          => 1,
    "description"           => 1,
    "element_data_type"     => 1,
    "element_index"         => 1,
    "valid_vals"            => $Opt_Valid_Vals,
    "valid_vals_label"      => $Opt_Valid_Vals
);

my %elements = ();
my @r_info = ();
my $action_name = "";
my $response_cnt = $#$response;
my %HoAttr = (); 
@$rLoSDAttr = ();

for ($r = 0; $r <= $response_cnt; $r++) {

    chomp($$response[$r]);
    @r_info = split (/$DELIMITER/, $$response[$r]);

    $action_name = $r_info[0];
    $action_name =~ s/^\"//;
    $action_name =~ s/\"$//;

    if ($HoRspAttr{"element_name"}) {
        %elements = ();
        $elements{at_name} = "element_name";
        $elements{at_dtype} = "CT_CHAR_PTR";
        $elements{at_value} = $r_info[1];
        build_HoAttr($elements{at_name}, $rLoSDAttr, \%HoAttr,
            \%elements, 0);
    }

    if ($HoRspAttr{"display_name"}) {
        %elements = ();
        $elements{at_name}  = "display_name";
        $elements{at_dtype} = "CT_CHAR_PTR";
        $elements{at_value} = $r_info[3];
        build_HoAttr($elements{at_name}, $rLoSDAttr, \%HoAttr,
            \%elements, 0);
    }

    if ($HoRspAttr{"description"}) {
        %elements = ();
        $elements{at_name} = "description";
        $elements{at_dtype} = "CT_CHAR_PTR";
        $elements{at_value} = $r_info[4];
        build_HoAttr($elements{at_name}, $rLoSDAttr, \%HoAttr, 
            \%elements, 0);
    }

    if ($HoRspAttr{"element_data_type"}) {
        %elements = ();
        $elements{at_name} = "element_data_type";
        $elements{at_dtype} = "CT_CHAR_PTR";
        $data_type = $r_info[2];
        $data_type =~ s/^CT_//;
        $data_type = lc $data_type;
        $elements{at_value} = "\"".$data_type."\"";
        build_HoAttr($elements{at_name}, $rLoSDAttr, \%HoAttr,
            \%elements, 0);
    }

    if ($HoRspAttr{"element_index"}) {
        %elements = ();
        $elements{at_name}  = "element_index";
        $elements{at_dtype} = "CT_UINT32";
        $elements{at_value} = $r_info[5];
        build_HoAttr($elements{at_name}, $rLoSDAttr, \%HoAttr,
            \%elements, 0);
    } 

        if ($HoRspAttr{"valid_vals"}) {
            %elements = ();
            $elements{at_name} = "valid_vals";
            ($elements{at_dtype}, $elements{at_value}) = 
                convert_sd_valid_values($response_vv, $r,
                    $response_vv->count($r), $data_type, 
                    $element_index);
            build_HoAttr($elements{at_name}, $rLoSDAttr, \%HoAttr, 
                \%elements, 0);
        }                                               

        if ($HoRspAttr{"valid_vals_label"}) {
            %elements = ();
            $elements{at_name} = "valid_vals_label";
            ($elements{at_dtype}, $elements{at_value}) = 
                convert_sd_valid_values_label($response_vv, $r,
                    $response_vv->count($r), $element_index, $data_type);
            build_HoAttr($elements{at_name}, $rLoSDAttr, \%HoAttr, 
                \%elements, 0);
        }

    # at the end of this definition for this action?
    if ( ($r == $response_cnt) || ($$response[$r+1] =~ /${DELIMITER}0\n$/) ) {

        # Put this SD Attribute definition in the hash with the rest of
        # the SD attributes definitions.
        push @actions, $action_name;                 
        $$rHoSDDefs{$action_name} = { %HoAttr };
    }

    if ( ($r < $response_cnt) && ($$response[$r+1] =~ /${DELIMITER}0\n$/) ) {
        %HoAttr = ();
        @$rLoSDAttr = ();
    }
}   # end for each response

# If actions specified on command line display in that order
# otherwise display in the order RMC returned them.
if (scalar @$r_actions < 0 && scalar @actions > 1) {
    push @$r_actions, @actions;
}

return;
}   # end of format_sd_defs


#--------------------------------------------------------------------#
# display_actions - displays the action names and values for         #
#   each element stored in %$rHoAttr. Only the actions that          #
#   are listed in the array $r_actions are displayed using the       #
#   appropriate output format (long, delimitter, or tabular).        #
#   If $r_actions is empty all actions in %$rHoAttr are displayed.   #
#                                                                    #
# Parameters:                                                        #
#   @$r_actions       input   Action names from command line.        #
#   @$rLoActions      input   Reference to List of Action Names      #
#   %$rHoActions      input   Reference to Hash of Actions           #
#                                                                    #
# Returns:                                                           #
#   $rc                       Return code (0 = success).             #
#                                                                    #
# Global References:                                                 #
#   $Opt_Long_Format  input   TRUE if should display one per line.   #
#   $Opt_Table_Format input   TRUE if should display in table form.  #
#   $Opt_Delm_Format  input   TRUE if should display with delimiter. #
#   $Opt_Delm_Str     input   Actual delimiter to display with.      #
#   $Opt_No_HDR       input   TRUE if should not display header.     #
#--------------------------------------------------------------------#
sub display_actions
{
my($r_actions, $rLoActions, $rHoActions) = @_;

my ($header, $row_title);
my $print_format = "long";
my $delim = "";
my $rc = 0;

# Determine if displaying in long, delimiter or tabular/column format.
if ($Opt_Long_Format) {
    $print_format = "long";
}
elsif ($Opt_Table_Format) {
    $print_format = "column";
}
elsif ($Opt_Delm_Format) {
    $print_format = "delim";
    $delim = $Opt_Delm_Str;
} 

# Display a catalogued message as the header instead of using
# the header printing capability of display_resource_data
$header = "";
if (!$Opt_No_HDR) {
    ($Opt_LS_Class) ? 
        printIMsg("IMsglsactdefLsRsrcClassActDefHdr", $resource) : 
        printIMsg("IMsglsactdefLsRsrcActDefHdr", $resource);
}
#$row_title = "action";
my @out_title = getIMsg("IMsglsactdefActionTitle");
$row_title = $out_title[0];

# Display the actions in the order that they were requested
# on the command line.  If no action names were specified on
# the command line display them in the order that RMC returned
# them.

if (scalar(@$r_actions) == 0) {
    $r_actions = $rLoActions;
}

# For debugging to reference one element
# $rHoActions->{$attr_name}[$row]{at_value}

$rc = display_resource_data_api2($print_format, $Opt_No_HDR, $r_actions,
        $row_title, $rHoActions, $delim, $header);

return $rc;
}   # end display_actions


#--------------------------------------------------------------------#
# display_sd_for_input - display the Resource or Resource Class      #
#   SD Action Input Element names and values (values are just the    #
#   data type since action elements do not have default values).     #
#   In a format suitable for input to runact after appropriate       #
#   manual editing.                                                  #
#                                                                    #
# Paramaters:                                                        #
#   @$r_actions       input   Reference to List of Action Names      #
#   %$rHoSDDefs       input   Reference to Hash of Actions and their #
#                             SD elements.                           #
#                                                                    #
# Returns:                                                           #
#   $rc                       0 - for success, non-zero - failure.   #
#                                                                    #
# Global References:                                                 #
#   $Opt_LS_Class     input   TRUE if displaying Class Action input. #
#   $Opt_Long_Format  input   TRUE if should display one per line.   #
#   $Opt_Table_Format input   TRUE if should display in table form.  #
#   $Opt_Delm_Format  input   TRUE if should display with delimiter. #
#   $Opt_Delm_Str     input   Actual delimiter to display with.      #
#   $Opt_No_HDR       input   TRUE if should not display header.     #
#--------------------------------------------------------------------#
sub display_sd_for_input
{
my($r_actions, $rHoSDDefs) = @_;

my $row_title = "structured_data";  # programmic name from ct.h
my $print_format = "long";          # input format is long format 
my $delim = "";
my $rc = 0;

(!$Opt_No_HDR && $Opt_LS_Class) &&
    print "ResourceClassAction::\n"; 
(!$Opt_No_HDR && !$Opt_LS_Class) &&
    print "ResourceAction::\n";

if (scalar @$r_actions < 1) {
    push @$r_actions, keys %$rHoSDDefs;
}


my @fields = ();                    # display all fields in HoSDDefs
my $i = 0;
foreach $action (@$r_actions) {
    ($i > 0) && print "\n";
    my $col_title = "# action_name = $action";
    # For debugging to reference one element
    # $rHoSDDefs->{$action_name}{$element_name}
    @fields = keys %{$$rHoSDDefs{$action}};
    $rc = display_resource_data_api2($print_format, $Opt_No_HDR, \@fields,
        $row_title, $$rHoSDDefs{$action}, $delim, $col_title);
    ($rc == 0) || return($rc);
    $i++;
}

return $rc;
}   # end display_sd_for_input


#--------------------------------------------------------------------#
# display_sd_defs - displays the SD definition for the action input  #
#   or response for the resource or resource class (-c) specified    #
#   on the command line.  Zero or more SDs may have been formatted   #
#   to be displayed.                                                 #
#                                                                    #
# Parameters:                                                        #
#   $resource         input   Name of resource.                      #
#   @$r_actions       input   Reference to an array of action names, #
#                             the ones to be displayed.              #
#   @$rLoSDAttr       input   Reference to List of SD Element field  #
#                             names.                                 #
#   %$rHoSDDefs       input   Reference to Hash of Actions and their #
#                             SD Elements.                           #
# Returns:                                                           #
#   $rc                       Return code (0 = success)              #
#                                                                    #
# Global References:                                                 #
#   $Opt_LS_Class     input   TRUE if listing resource class SD defs #
#   $Opt_SD_Input     inupt   TRUE  if listing SD action input defs. #
#                             FALSE if listing SD response defs.     #
#   $Opt_Long_Format  input   TRUE if should display one per line.   #
#   $Opt_Table_Format input   TRUE if should display in table form.  #
#   $Opt_Delm_Format  input   TRUE if should display with delimiter. #
#   $Opt_Delm_Str     input   Actual delimiter to display with.      #
#   $Opt_No_HDR       input   TRUE if should not display header.     #
#--------------------------------------------------------------------#
sub display_sd_defs 
{
my($resource, $r_actions, $rLoSDAttr, $rHoSDDefs) = @_;

my $print_format = "long";
my $delim = "";
my $rc = 0;

# Determine if displaying in long, delimiter or tabular/column format.
if ($Opt_Long_Format) {
    $print_format = "long";
}
elsif ($Opt_Table_Format) {
    $print_format = "column";
}
elsif ($Opt_Delm_Format) {
    $print_format = "delim";
    $delim = $Opt_Delm_Str;
} 

# Display a header for the data using a catalgued message
if (!$Opt_No_HDR) {
    if ($Opt_LS_Class) {
        ($Opt_SD_Input) ? 
            printIMsg("IMsglsactdefLsRsrcClassActInHdr", $resource) : 
            printIMsg("IMsglsactdefLsRsrcClassActRspHdr", $resource);
    } 
    else {
        ($Opt_SD_Input) ? 
            printIMsg("IMsglsactdefLsRsrcActInHdr", $resource) : 
            printIMsg("IMsglsactdefLsRsrcActRspHdr", $resource);
    }
}
    
# Display the action SD elements in the order that they were requested
# on the command line. If no Action names were specified on the command
# line display them in the order that RMC returned them.
if (scalar @$r_actions < 1) {
    push @$r_actions, keys %$rHoSDDefs;
}

my $row_title = "sd_element";       # use programmic name for NLS
my $i = 0;
foreach $action (@$r_actions) {
    ($i > 0) && print "\n";
    my $col_title = "action_name $action:"; 
    $rc = display_resource_data_api2($print_format, $Opt_No_HDR, $rLoSDAttr,
        $row_title, $$rHoSDDefs{$action}, $delim, $col_title);
    ($rc == 0) || return($rc);    
    $i++;
}

return($rc);
}   # end display_sd_defs


#--------------------------------------------------------------------#
# display_attributes_api - displays the attributes names and values  #
#   for each element stored in %$rHoAttr. Only the attributes that   #
#   are listed in the array $r_attributes are displayed using the    #
#   appropriate output format (long, delimitter, or tabular).        #
#   If $r_attributes is empty all attributes in %$rHoAttr are        #
#   displayed.                                                       #
#                                                                    #
# Parameters:                                                        #
#   $col_title        input   Title/Header that gets displayed       #
#                             before any attributes.                 #
#   $row_title        input   Title/Header that gets displayed       #
#                             before each new attribute.             #
#   @$r_attributes    input   Attribute names from command line.     #
#   @$rLoAttr         input   Reference to List of Attributes Names  #
#   %$rHoAttr         input   Reference to Hash of Attributes        #
#                                                                    #
# Returns:                                                           #
#   $rc                       Return code.                           #
#                                                                    #
# Global References:                                                 #
#   $Opt_Long_Format  input   TRUE if should display one per line.   #
#   $Opt_Table_Format input   TRUE if should display in table form.  #
#   $Opt_Delm_Format  input   TRUE if should display with delimiter. #
#   $Opt_Delm_Str     input   Actual delimiter to display with.      #
#   $Opt_No_HDR       input   TRUE if should not display header.     #
#--------------------------------------------------------------------#
sub display_attributes_api
{
my($col_title, $row_title, $r_attributes, $rLoAttr, $rHoAttr) = @_;

my $print_format = "long";
my $delim = "";

# Determine if displaying in long, delimiter or tabular/column format.
if ($Opt_Long_Format) {
    $print_format = "long";
}
elsif ($Opt_Table_Format) {
    $print_format = "column";
}
elsif ($Opt_Delm_Format) {
    $print_format = "delim";
    $delim = $Opt_Delm_Str;
}

# Display the attributes in the order that they were requested
# on the command line.  If no attribute names were specified on
# the command line display them in the order that RMC returned
# them.

if (scalar(@$r_attributes) == 0) {
    $r_attributes = $rLoAttr;
}

# For debugging to reference one element
# $rHoAttr->{$attr_name}[$row]{at_value}

my $rc = display_resource_data_api($print_format, $Opt_No_HDR,
    $r_attributes, $row_title, $rHoAttr, $delim, $col_title);

return $rc;
}   # end display_attributes_api


#--------------------------------------------------------------------#
# qdef_valid_vals - function to call the CT::MC::qdef_valid_         #
#   values_bp extension. Based on above code.                        #
#                                                                    #
# Parameters:                                                        #
#   $session          input   RMC session handle.                    #
#   $resource         input   Name of the resource class whose attr  #
#                             definitions we want.                   #
#   @$r_attributes    input   Reference to array of attribute names. #
#   $response         in/out  Response data structure, on output     #
#                             this will point to the real resposne.  #
#   $usage            input   One of mc_vv_usage_t enum types.       #
#                                                                    #
# Return:                                                            #
#   $rc                       return code.                           #
#                                                                    #
# Global References:                                                 #
#   $Opt_Exp_Desc     input   TRUE if display def & description.     #
#                                                                    #
#TODO: While support for retrieving valid values through action      #
#      invokation is documented in the API, as of 8/6/01, it has not #
#      yet been implemented. Once it is implemented in the RMC C API,#
#      support for retrieving valid values using actions should be   #
#      added to this command.                                        #
#--------------------------------------------------------------------#
sub qdef_valid_vals
{
my ($session, $resource, $r_actions, $response, $usage) = @_;
my $rc = 0;

my $options = $Opt_Exp_Desc ? MC_QDEF_OPTS_NONE : MC_QDEF_OPTS_NODSCRP;

my $error = CT::MC::errnum_t->new;

my $act_count = scalar(@$r_actions); 

$Trace && print STDERR "Calling CT::MC::qdef_valid_values_bp\n";

$rc = CT::MC::qdef_valid_values_bp($session, $response, $error,
                                   $options, $resource, $usage, 
                                   $r_actions, $act_count);

$Trace && print STDERR "Return  CT::MC::qdef_valid_values_bp\n";

$rc = error_check("mc_qdef_valid_values_bp", $resource, $response, 
    $rc, $error);

return $rc;
}   # end qdef_valid_vals


#--------------------------------------------------------------------#
# error_check - checks the return code from the RMC function and     #
#   the error response return code.  If an error is detected         #
#   appropriate error messages will be displayed.                    #
#                                                                    #
# Parameters:                                                        #
#   $rmc_function     in      Name of the rmc function that was      #
#                             called and whose error code we are     #
#                             checking.                              #
#   $rmc_class        in      The rmc class name.                    #
#   $response         in      RMC response                           #
#   $rmc_rc           in      The rmc function return code.          #
#   $error            in      The error response.                    #
#                                                                    #
# Return:                                                            #
#   $rc                       return code.                           #
#                                                                    #
# Global References:                                                 #
#   None.                                                            #
#--------------------------------------------------------------------#
sub error_check
{
my ($rmc_function, $rmc_class, $response, $rmc_rc, $error) = @_;

my $rc = 0;
my $err_rc = $error->errnum();

if ($rmc_rc != 0) {
    printEMsg("EMsglsactdefLsActDefError", $rmc_class);
    my $rmc_rc_hex = sprintf "0x%8.8lx", $rmc_rc;
    printCEMsg("EMsgMCcliMCFunctionFailure", $rmc_function, 
        $rmc_rc, $rmc_rc_hex);
    $rc = MC_CLI_RMC_ERROR;
    return $rc;
}

# Check the errnum in each of the RMC responses
for (my $r = 0; $r < $response->array_count; $r++) {
    # get the error that goes with the specific response
    if ($r > 0) {
        $response->error($error, $r);
        $err_rc = $error->errnum();
    }
    if ($err_rc != 0) {
        if ($err_rc == RMC_ECLASSNOTDEFINED) {
            printCEMsg("EMsgMCcliClassNotDef", $rmc_class);
            $rc = MC_CLI_USER_ERROR;
        }
        elsif ($err_rc == RMC_EBADACTIONNAM) {
            print STDERR $error->error_msg;
            $rc = MC_CLI_USER_ERROR;
        }   
        elsif ($err_rc == RMC_EACCESS) {
            print STDERR $error->error_msg;
            $rc = MC_CLI_USER_ERROR;
        }
        else {
            printEMsg("EMsglsactdefLsActDefError", $rmc_class);
            my $err_rc_hex = sprintf "0x%8.8lx", $err_rc;
            printCEMsg("EMsgMCcliMCFunctionFailure", $rmc_function, 
                $err_rc, $err_rc_hex);
            print STDERR $error->error_msg; 
            $rc = MC_CLI_RMC_ERROR;
        }
    }   # end if
}   # end for

return $rc;
}   # end error_check