# $Header: ecmCollectCSA.pl 03-jun-2008.12:16:39 jashukla Exp $
#
# Copyright (c) 2003, 2006, Oracle. All rights reserved.  
#
# NAME
#   ecmCollectCSA.pl
#
# DESCRIPTION
#   ECM script to convert CSA collection files to loader files
#
# USAGE
#   perl ecmCollectCSA.pl <options>
#
#     options:
#       -emdroot "%emdRoot%"                 : Location of Agent Oracle home
#       -outfile "%loaderFile%"              : Filename of external metric file
#       -targetguid "%targetGUID%"           : SYS_GUID of target
#       -indir "%recvFileDir%"               : CSA Applet receive directory
#       -emdURL "%emdURL%"                   : URL of Management Agent
#       -omsversion "%OMS_VERSION%"          : OMS version from Agent
#
# EXAMPLE
#   $PERL $EMDROOT/sysman/admin/scripts/osm/ecmCollectCSA.pl        \
#       -emdroot "$EMDROOT"                                         \
#       -outfile "$EMDROOT/sysman/emd/upload/F7.ext"                \
#       -targetguid "AE4E5787E7965BA420FD10962D782636"              \
#       -indir "$EMDROOT/sysman/emd/csa/recv"                       \
#       -emdURL "http://host.example..com:5125/emd/main/"       \
#       -omsversion "10.2.0.0.0"
#
# NOTES
#   <other useful comments,qualifications,etc>
#
# MODIFIED    (MM/DD/YY)
#   jashukla   06/03/08 - Bug 7144619 remove internal identifiers
#   bkesavan   09/14/06 - Add getFileList
#   mgoodric   04/18/05 - record possible DOS attacks to OMS
#   asaraswa   02/18/05 - changing defaults for appid and worst_rule_status
#   asaraswa   02/09/05 - adding BROWSER_PROXY_ENABLED and AUTO_CONFIG_URL
#                         columns
#   mgoodric   02/04/05 - fixed parsing for <COLUMN>
#   mgoodric   02/03/05 - fix parsing for backward compatibility
#   mgoodric   02/02/05 - add parsing for valid table/columns only
#   mgoodric   01/30/05 - add verifying XML contents based on OMS_VERSION
#   vkhizder   07/15/04 - adding processing for failed CSA collections
#   mgoodric   05/10/04 - fix using /.. which does not work in vob split
#   mgoodric   10/21/03 - add creating empty xxx.ext0.1 metric file
#   mgoodric   09/26/03 - mgoodric_add_csa_proxy_target_030922
#   mgoodric   09/26/03 - changed snapshot_type to oracle_csa
#   mgoodric   09/22/03 - created

# --- Set up necessary variables for proper running of this environment ---

use strict;

use File::Basename();
use File::Spec();

use FindBin qw ( $Bin );
use lib "$Bin";

require "ecmCommon.pl";

my $scriptName = File::Basename::basename($0);
my $scriptsDir = File::Basename::dirname($0); $scriptsDir =~ s/.osm$//;
my $emdCommon  = File::Spec->catfile($scriptsDir, 'emd_common.pl');

require "$emdCommon";

##*********************************************************************
##                    I N I T I A L I Z A T I O N
##*********************************************************************

BEGIN {
    use constant COPYRIGHT       => "Copyright (c) 2003, 2006, Oracle. All rights reserved.";
    use constant VERSION         => '10.2.0.0';
    use constant OMS_VERSION     => '10.2.0.0.0';
    use constant TARGET_VERSION  => '1.0';
    use constant COLLECTION_NAME => 'oracle_csa';
    use constant CONFIG_VALUE    => 'TRUE';
    use constant MULTIFILE_EXT   => '0.';
    use constant ERROR_PREFIX    => 'ERROR: ECM';
    use constant ECM_PREFIX      => 'ECM';
    use constant S_DEBUG         => '-debug';
    use constant S_EMDROOT       => '-emdroot';
    use constant S_EMDURL        => '-emdURL';
    use constant S_HELP          => '-help';
    use constant S_INDIR         => '-indir';
    use constant S_OMSVERSION    => '-omsversion';
    use constant S_OUTFILE       => '-outfile';
    use constant S_TARGETGUID    => '-targetguid';
    use constant S_VERSION       => '-version';
    use constant S_EMPTY         => '';
    use constant B_TRUE          => 1;
    use constant B_FALSE         => 0;
    use constant E_SUCCESS       => 0;
    use constant E_FAIL          => 1;

    # --------------------- Command-line parameters -------------------------

    use vars qw ( $EMDROOT $ORACLE_HOME $OMS_version );
    ($EMDROOT, $ORACLE_HOME, $OMS_version) =
        ($ENV{'EMDROOT'}, $ENV{'ORACLE_HOME'}, '10.1.0.3.0');

    use vars qw ( $emd_url $loader_file $recv_dir $target_guid );
    ($emd_url, $loader_file, $recv_dir, $target_guid) =
        (S_EMPTY, 'F1.ext', S_EMPTY, S_EMPTY);

    # --------------------- Variables ---------------------------------------

    use vars qw ( $count $debug_opt $numOfSucCollections $tableCount $isInvalid);
    ($count, $debug_opt, $numOfSucCollections, $tableCount, $isInvalid) =
        (0, 0, 0, 0, B_FALSE);

    use vars qw ( $errMsg $errLine $infile $outfile $suc_mask $fail_mask );
    ($errMsg, $errLine, $infile, $outfile, $suc_mask, $fail_mask) =
        (S_EMPTY, S_EMPTY, S_EMPTY, S_EMPTY, S_EMPTY, S_EMPTY);

    use vars qw ( @files @tables %tableMap );
}

END {
    exit($?);
}

##*********************************************************************
##                        F U N C T I O N S
##*********************************************************************

#======================================================================
# printUsage()
#
# Display our help frame
#======================================================================
sub printUsage() {
    print STDOUT <<_EOM_

Usage: perl $scriptName <options>

  options:
      -emdroot "%emdRoot%"                 : Location of Agent Oracle home
      -outfile "%loaderFile%"              : Filename of external metric file
      -targetguid "%targetGUID%"           : SYS_GUID of target
      -indir "%recvFileDir%"               : Path of Applet receive directory
      -emdURL "%emdURL%"                   : URL of Agent
      -omsversion "%OMS_VERSION%"          : Version of OMS

Example:

  \$PERL \$EMDROOT/sysman/admin/scripts/osm/ecmCollectCSA.pl      \\
    -emdroot "\$EMDROOT"                                         \\
    -outfile "\$EMDROOT/sysman/emd/upload/F7.ext"                \\
    -targetguid "AE4E5787E7965BA420FD10962D782636"              \\
    -indir "\$EMDROOT/sysman/emd/csa/recv"                       \\
    -emdURL "http://host.example.com:5125/emd/main/"       \\
    -omsversion "10.2.0.0.0"

_EOM_
        ;
}

#======================================================================
# printVersion()
#
# Display our version and copyright
#======================================================================
sub printVersion() {
    printf(STDOUT "\n%s Version %s\n%s\n\n", $scriptName, VERSION, COPYRIGHT);
}

#======================================================================
# getUniqueOutput()
#
# Returns: next available output filename
#======================================================================
sub getUniqueOutput() {
    my $filename = S_EMPTY;

    do {
        $count++;
        $filename = $loader_file . MULTIFILE_EXT . $count;
    } while (-f $filename);

    return $filename;
}

#======================================================================
# populateTables(<version>)
#
# Create the list of tables/columns by OMS version
#
# Returns: @tables
#======================================================================
sub populateTables($) {
    my ($version) = @_;

    $version =~ s/[.]//g;    # converts 10.2.0.0.0 => 102000 or 10.1.0.3.0 => 101030

    my @MGMT_ECM_CSA_SNAPSHOT_INFO = (
        "MGMT_ECM_CSA_SNAPSHOT_INFO",    #
        "DISPLAY_TARGET_NAME",           # VARCHAR2(256)
        "SNAPSHOT_TYPE",                 # VARCHAR2(64)
        "START_TIMESTAMP",               # DATE
        "ELAPSED_TIME",                  # NUMBER(16), NOT NULL
        "STATUS",                        # VARCHAR2(1)
        "MESSAGE"                        # VARCHAR2(4000)
    );

    my @MGMT_ECM_CSA_GENERAL_INFO = (
        "MGMT_ECM_CSA_GENERAL_INFO",      #
        "APPLET_VERSION",                 # VARCHAR2(20)
        "CUSTOM_CLASS",                   # VARCHAR2(1000)
        "CUSTOM_CLASS_VERSION",           # VARCHAR2(1000)
        "TARGET_ID_METHOD",               # VARCHAR2(100), NOT NULL
        "OS_USER_NAME",                   # VARCHAR2(500), NOT NULL
        "BOOT_DISK_VOLUME_SERIAL_NUM",    # VARCHAR2(100), NOT NULL
        "HOSTNAME",                       # VARCHAR2(128), NOT NULL
        "DOMAIN",                         # VARCHAR2(500), NOT NULL
        "TARGET_KEY1",                    # VARCHAR2(4000)
        "TARGET_KEY2",                    # VARCHAR2(4000)
        "TARGET_KEY3"                     # VARCHAR2(4000)
    );

    if ($version >= 102000) {
        @MGMT_ECM_CSA_GENERAL_INFO = (
            @MGMT_ECM_CSA_GENERAL_INFO,    #
            "APPID",                       # VARCHAR2(128)
            "WORST_RULE_STATUS"            # NUMBER
        );
    }

    my @MGMT_ECM_CSA = (
        "MGMT_ECM_CSA",                    #
        "NET_LATENCY_IN_MS",               # NUMBER
        "NET_BANDWIDTH_IN_KBITPS",         # NUMBER
        "NET_EFFECTIVE_IP",                # VARCHAR2(20)
        "NET_IP",                          # VARCHAR2(20)
        "NET_SUBNET",                      # VARCHAR2(20)
        "BROWSER_TYPE",                    # VARCHAR2(100)
        "BROWSER_VERSION",                 # VARCHAR2(20)
        "BROWSER_JVM_VENDOR",              # VARCHAR2(100)
        "BROWSER_JVM_VERSION",             # VARCHAR2(20)
        "BROWSER_PROXY_SERVER",            # VARCHAR2(4000)
        "BROWSER_PROXY_EXCEPTIONS",        # VARCHAR2(4000)
        "BROWSER_CACHE_SIZE_IN_MB",        # NUMBER
        "BROWSER_CACHE_UPDATE_FRQ",        # VARCHAR2(200)
        "BROWSER_HTTP1_1_SUPPORT",         # VARCHAR2(1)
        "REFERRING_URL_HEADER",            # VARCHAR2(4000)
        "REFERRING_URL_PARAMS",            # VARCHAR2(4000)
        "CSA_URL_HEADER",                  # VARCHAR2(4000)
        "CSA_URL_PARAMS",                  # VARCHAR2(4000)
        "DESTINATION_URL_HEADER",          # VARCHAR2(4000)
        "DESTINATION_URL_PARAMS"           # VARCHAR2(4000)
    );
    if ($version >= 102000) {
        @MGMT_ECM_CSA = (
            @MGMT_ECM_CSA,                 #
            "IS_WINDOWS_ADMIN",            # VARCHAR2(1)
            "WINDOWS_DOMAIN",              # VARCHAR2(100)
            "CONNECTION_TYPE",             # NUMBER
            "BROWSER_PROXY_ENABLED",       # VARCHAR2(1)
            "AUTO_CONFIG_URL"              # VARCHAR2(4000)
        );
    }

    my @MGMT_ECM_CSA_COOKIES = (
        "MGMT_ECM_CSA_COOKIES",            #
        "NAME",                            # VARCHAR2(4000)
        "VALUE"                            # VARCHAR2(4000)
    );

    my @MGMT_ECM_HW = (
        "MGMT_ECM_HW",                     #
        "HOSTNAME",                        # VARCHAR2(128)
        "DOMAIN",                          # VARCHAR2(500)
        "VENDOR_NAME",                     # VARCHAR2(128)
        "SYSTEM_CONFIG",                   # VARCHAR2(4000)
        "MACHINE_ARCHITECTURE",            # VARCHAR2(500)
        "CLOCK_FREQ_IN_MHZ",               # NUMBER
        "MEMORY_SIZE_IN_MB",               # NUMBER
        "AVAIL_MEMORY_SIZE_IN_MB",         # NUMBER
        "LOCAL_DISK_SPACE_IN_GB",          # NUMBER
        "AVAIL_LOCAL_DISK_SPACE_IN_GB",    # NUMBER
        "CPU_COUNT",                       # NUMBER(8)
        "CPU_BOARD_COUNT",                 # NUMBER(8)
        "IOCARD_COUNT",                    # NUMBER(8)
        "FAN_COUNT",                       # NUMBER(8)
        "POWER_SUPPLY_COUNT",              # NUMBER(8)
        "BOOT_DISK_VOLUME_SERIAL_NUM"      # VARCHAR2(100)
    );
    if ($version >= 102000) {
        @MGMT_ECM_HW = (
            @MGMT_ECM_HW,                  #
            "SYSTEM_BIOS",                 # VARCHAR2(100)
            "SYSTEM_SERIAL_NUMBER"         # VARCHAR2(100)
        );
    }

    my @MGMT_ECM_HW_CPU = (
        "MGMT_ECM_HW_CPU",                 #
        "VENDOR_NAME",                     # VARCHAR2(128)
        "FREQ_IN_MHZ",                     # NUMBER
        "ECACHE_IN_MB",                    # NUMBER
        "IMPL",                            # VARCHAR2(500)
        "REVISION",                        # VARCHAR2(2000)
        "MASK"                             # VARCHAR2(500)
    );

    my @MGMT_ECM_HW_IOCARD = (
        "MGMT_ECM_HW_IOCARD",              #
        "VENDOR_NAME",                     # VARCHAR2(128)
        "NAME",                            # VARCHAR2(128), NOT NULL
        "FREQ_IN_MHZ",                     # NUMBER
        "BUS",                             # VARCHAR2(500)
        "REVISION"                         # VARCHAR2(2000)
    );

    my @MGMT_ECM_HW_NIC = (
        "MGMT_ECM_HW_NIC",                 #
        "NAME",                            # VARCHAR2(128)
        "DESCRIPTION",                     # VARCHAR2(500)
        "FLAGS",                           # VARCHAR2(1024)
        "MAX_TRANSFER_UNIT",               # NUMBER
        "INET_ADDRESS",                    # VARCHAR2(20)
        "MASK",                            # VARCHAR2(20)
        "BROADCAST_ADDRESS",               # VARCHAR2(20)
        "MAC_ADDRESS",                     # VARCHAR2(20)
        "HOSTNAME_ALIASES",                # VARCHAR2(4000)
        "DEFAULT_GATEWAY",                 # VARCHAR2(20)
        "DHCP_ENABLED"                     # VARCHAR2(1)
    );

    my @MGMT_ECM_OS = (
        "MGMT_ECM_OS",                     #
        "NAME",                            # VARCHAR2(128)
        "VENDOR_NAME",                     # VARCHAR2(128)
        "BASE_VERSION",                    # VARCHAR2(100)
        "UPDATE_LEVEL",                    # VARCHAR2(100)
        "DISTRIBUTOR_VERSION",             # VARCHAR2(100)
        "MAX_SWAP_SPACE_IN_MB",            # NUMBER
        "ADDRESS_LENGTH_IN_BITS",          # VARCHAR2(20)
        "MAX_PROCESS_VIRTUAL_MEMORY",      # NUMBER
        "TIMEZONE",                        # VARCHAR2(64)
        "TIMEZONE_REGION",                 # VARCHAR2(64)
        "TIMEZONE_DELTA"                   # NUMBER
    );

    my @MGMT_ECM_OS_COMPONENT = (
        "MGMT_ECM_OS_COMPONENT",           #
        "NAME",                            # VARCHAR2(128)
        "TYPE",                            # VARCHAR2(100)
        "VERSION",                         # VARCHAR2(100)
        "DESCRIPTION",                     # VARCHAR2(2000)
        "INSTALLATION_DATE"                # DATE
    );

    my @MGMT_ECM_OS_PROPERTY = (
        "MGMT_ECM_OS_PROPERTY",            #
        "SOURCE",                          # VARCHAR2(128), NOT NULL
        "NAME",                            # VARCHAR2(128), NOT NULL
        "VALUE"                            # VARCHAR2(2000)
    );

    my @MGMT_ECM_OS_FILESYSTEM = (
        "MGMT_ECM_OS_FILESYSTEM",          #
        "RESOURCE_NAME",                   # VARCHAR2(128), NOT NULL
        "MOUNT_LOCATION",                  # VARCHAR2(128), NOT NULL
        "TYPE",                            # VARCHAR2(100)
        "DISK_SPACE_IN_GB",                # NUMBER
        "AVAIL_DISK_SPACE_IN_GB",          # NUMBER
        "LOCAL_DRIVE",                     # VARCHAR2(1)
        "MOUNT_OPTIONS"                    # VARCHAR2(1024)
    );

    my @MGMT_ECM_OS_REGISTERED_SW = (
        "MGMT_ECM_OS_REGISTERED_SW",       #
        "ID",                              # VARCHAR2(500)
        "NAME",                            # VARCHAR2(128), NOT NULL
        "VENDOR_NAME",                     # VARCHAR2(128)
        "VERSION",                         # VARCHAR2(100)
        "INSTALLATION_DATE",               # DATE
        "INSTALLED_LOCATION",              # VARCHAR2(1024)
        "DESCRIPTION",                     # VARCHAR2(2000)
        "VENDOR_SW_SPECIFIC_INFO"          # VARCHAR2(4000)
    );

    my @MGMT_ECM_CSA_CUSTOM = (
        "MGMT_ECM_CSA_CUSTOM",             #
        "TYPE",                            # VARCHAR2(512)
        "NAME",                            # VARCHAR2(512), NOT NULL
        "TYPE_UI",                         # VARCHAR2(4000)
        "NAME_UI",                         # VARCHAR2(4000)
        "VALUE",                           # VARCHAR2(4000)
        "DISPLAY_UI",                      # VARCHAR2(1)
        "HISTORY_TRACKING"                 # VARCHAR2(1)
    );

    my @MGMT_ECM_CSA_FAILED = (
        "MGMT_ECM_CSA_FAILED",             #
        "TIMESTAMP",                       # DATE
        "TIMEZONE_DELTA",                  # NUMBER
        "EFFECTIVE_IP",                    # VARCHAR2(20)
        "APPID",                           # VARCHAR2(128)
        "REFERRING_URL_HEADER",            # VARCHAR2(4000)
        "REFERRING_URL_PARAMS",            # VARCHAR2(4000)
        "CSA_URL_HEADER",                  # VARCHAR2(4000)
        "CSA_URL_PARAMS",                  # VARCHAR2(4000)
        "DESTINATION_URL_HEADER",          # VARCHAR2(4000)
        "DESTINATION_URL_PARAMS",          # VARCHAR2(4000)
        "BROWSER_TYPE",                    # VARCHAR2(100)
        "BROWSER_VERSION",                 # VARCHAR2(20)
        "BROWSER_JVM_VENDOR",              # VARCHAR2(100)
        "BROWSER_JVM_VERSION",             # VARCHAR2(20)
        "OS_ARCH",                         # VARCHAR2(100)
        "OS_NAME",                         # VARCHAR2(100)
        "HTTP_REQUEST_USER_AGENT",         # VARCHAR2(100)
        "ERROR_CODE",                      # VARCHAR2(1)
        "ERROR_TEXT"                       # VARCHAR2(1024)
    );

    my @MGMT_ECM_CSA_RULES = ();
    if ($version >= 102000) {
        @MGMT_ECM_CSA_RULES = (
            "MGMT_ECM_CSA_RULES",          #
            "NAME",                        # VARCHAR2(128), NOT NULL
            "DESCRIPTION",                 # VARCHAR2(256)
            "STATUS",                      # NUMBER
            "MOREINFO"                     # VARCHAR2(1024)
        );
    }

    @tables = (
        @MGMT_ECM_CSA_SNAPSHOT_INFO,       #
        @MGMT_ECM_CSA_GENERAL_INFO,        #
        @MGMT_ECM_CSA,                     #
        @MGMT_ECM_CSA_COOKIES,             #
        @MGMT_ECM_HW,                      #
        @MGMT_ECM_HW_CPU,                  #
        @MGMT_ECM_HW_IOCARD,               #
        @MGMT_ECM_HW_NIC,                  #
        @MGMT_ECM_OS,                      #
        @MGMT_ECM_OS_COMPONENT,            #
        @MGMT_ECM_OS_PROPERTY,             #
        @MGMT_ECM_OS_FILESYSTEM,           #
        @MGMT_ECM_OS_REGISTERED_SW,        #
        @MGMT_ECM_CSA_CUSTOM,              #
        @MGMT_ECM_CSA_FAILED,              #
        @MGMT_ECM_CSA_RULES                #
    );
}

#======================================================================
# getTableMap(<version>)
#
# Construct a table map for an OMS version
#
# Return: %tableList
#======================================================================
sub getTableMap($) {
    my ($version) = @_;

    my $tableName = S_EMPTY;
    my %tableList = ();

    populateTables($version);

    foreach my $entry (@tables) {
        if ($entry =~ m/^MGMT_ECM_/) {
            $tableName = $entry;
            $tableList{$tableName} = B_TRUE;
            $tableCount++;
        }
        else {
            $tableList{$tableName . '.' . $entry} = B_TRUE;
        }
    }

    return %tableList;
}

#======================================================================
# getNumericArg(<opt>,<i>)
#
# Parse the argument as numeric
#
# Returns: value
#======================================================================
sub getNumericArg($$) {
    my ($opt, $i) = @_;

    my $value = S_EMPTY;

    $value = getStringArg($opt, $i);
    if (!isNumeric($value)) {
        $errMsg = sprintf("%s: invalid value for '%s': %s\n", ERROR_PREFIX, $opt, $value);
        printf(STDERR "%s\n", $errMsg);
        exit(E_FAIL);
    }

    return $value;
}

#======================================================================
# getStringArg(<opt>,<i>)
#
# Parse the argument as string
#
# Returns: value
#======================================================================
sub getStringArg($$) {
    my ($opt, $i) = @_;

    my $value = S_EMPTY;

    if ($i < (scalar(@ARGV) - 1)) {
        $i++;
        $value = $ARGV[$i];
    }
    else {
        $errMsg = sprintf("%s: missing argument for '%s'\n", ERROR_PREFIX, $opt);
        printf(STDERR "%s\n", $errMsg);
        exit(E_FAIL);
    }

    return $value;
}

#======================================================================
# parseArgs()
#
# Parse the arguments and store them away for future use
#======================================================================
sub parseArgs() {
    my $argc = scalar(@ARGV);

    if ($argc == 0) {
        printUsage();
        exit(E_SUCCESS);
    }

    for (my $i = 0 ; $i < $argc ; $i++) {
        my $option = $ARGV[$i];

        if (isEqual(S_EMDROOT, $option)) {
            $EMDROOT = convertToUnix(getStringArg($option, $i));
            $i++;
        }
        elsif (isEqual(S_INDIR, $option)) {
            $recv_dir = convertToUnix(getStringArg($option, $i));
            $i++;
        }
        elsif (isEqual(S_TARGETGUID, $option)) {
            $target_guid = getStringArg($option, $i);
            $i++;
        }
        elsif (isEqual(S_EMDURL, $option)) {
            $emd_url = getStringArg($option, $i);
            $i++;
        }
        elsif (isEqual(S_OUTFILE, $option)) {
            $loader_file = convertToUnix(getStringArg($option, $i));
            $i++;
        }
        elsif (isEqual(S_OMSVERSION, $option)) {
            $OMS_version = getStringArg($option, $i);
            $i++;
        }
        elsif (isMatch(S_DEBUG, $option)) {
            $debug_opt = 1;
        }
        elsif (isMatch(S_HELP, $option)) {
            printUsage();
            exit(E_SUCCESS);
        }
        elsif (isMatch(S_VERSION, $option)) {
            printVersion();
            exit(E_SUCCESS);
        }
        else {
            $errMsg = sprintf("%s: invalid argument '%s'\n", ERROR_PREFIX, $option);
            printf(STDERR "%s\n", $errMsg);

            #exit(E_FAIL);
        }
    }

    return;
}

##*********************************************************************
##                    M A I N  P R O G R A M
##*********************************************************************

# auto flush STDOUT and STDERROR
setOutputAutoflush();

# make sure arguments are correct
parseArgs();

# find all CSA files ready for processing
$suc_mask = $recv_dir . '/CSA*.xml';
push(@files, getFileList($suc_mask));

$numOfSucCollections = scalar(@files);

# add failed collections to the array of files
$fail_mask = $recv_dir . '/fCSA*.xml';
push(@files, getFileList($fail_mask));

# convert all CSA*.xml and fCSA*.xml files to Agent loader xxx.ext0.n files
my $i = 0;
FILE: foreach $infile (@files) {
    $isInvalid = B_FALSE;

    if ($debug_opt != 0) {
        printf(STDOUT "%s\n", $infile);
    }

    open(INPUT, "< $infile") or next;

    $outfile = getUniqueOutput();
    if (!open(OUTPUT, "> $outfile")) {
        $errMsg = sprintf("%s: cannot open output file '%s'\n", ECM_PREFIX, $outfile);
        EMD_PERL_ERROR($errMsg);
        last FILE;
    }

    # print header
    printf(OUTPUT "<UPLOAD");
    printf(OUTPUT " OMS_PROTOCOL_VERSION=\"%s\"", OMS_VERSION);
    printf(OUTPUT " EMD_URL=\"%s\"",              $emd_url);
    printf(OUTPUT " VERSION=\"%s\"",              TARGET_VERSION);
    printf(OUTPUT " TARGET_GUID=\"%s\"",          $target_guid);
    printf(OUTPUT " COLLECTION_TIMESTAMP=\"%s\"", currentDate());

    if ($i < $numOfSucCollections) {
        printf(OUTPUT " COLLECTION_NAME=\"%s\"", COLLECTION_NAME);
        printf(OUTPUT " CONFIG=\"%s\"",          CONFIG_VALUE);
    }

    printf(OUTPUT ">\n");

    # construct valid table.column list
    if ($tableCount == 0) {
        %tableMap = getTableMap($OMS_version);
    }

    my $tableName  = S_EMPTY;
    my $columnName = S_EMPTY;
    my $inROWSET   = B_FALSE;
    my $inROW      = B_FALSE;

LINE: while (<INPUT>) {

        # looking for <ROWSET>
        if ($inROWSET == B_FALSE) {
            if (m/^\s*<\s*ROWSET\s.*TABLE="[\w]+"/) {
                chomp($tableName = $_);
                $tableName =~ s/^\s*<\s*ROWSET\s.*TABLE="([\w]+)".*/$1/;
                if (!isEmpty($tableName) && defined $tableMap{$tableName}) {

                    # dont let another tag hide behind a <ROWSET> tag
                    if (m/>\s*</) {
                        chomp($errLine = $_);
                        $isInvalid = B_TRUE;
                        last LINE;
                    }

                    printf(OUTPUT "%s", $_);
                    $inROWSET = B_TRUE;
                    $inROW    = B_FALSE;
                }
            }
            next;
        }

        # looking for </ROWSET> or <ROW>
        if ($inROW == B_FALSE) {
            if (m/^\s*<\s*\/ROWSET\s*>\s*$/s) {
                printf(OUTPUT "%s", $_);
                $inROWSET = B_FALSE;
            }
            elsif (m/^\s*<\s*ROW\s*>\s*$/s) {
                printf(OUTPUT "%s", $_);
                $inROW = B_TRUE;
            }
            next;
        }

        # looking for </ROW>
        if (m/^\s*<\s*\/ROW\s*>\s*$/s) {
            printf(OUTPUT "%s", $_);
            $inROW = B_FALSE;
            next;
        }

        # looking for <COLUMN> or <COLUMN/>
        if (m/^\s*<\s*[\w]+\s*[\/>]/s) {
            chomp($columnName = $_);
            $columnName =~ s/^\s*<\s*([\w]+).*/$1/;
            if (!isEmpty($columnName)
                && defined $tableMap{$tableName . '.' . $columnName}) {

                # dont let another tag hide behind a <COLUMN> tag
                if (   m/<\s*\/$columnName\s*>\s*</
                    || m/<\s*$columnName\/\s*>\s*</) {
                    chomp($errLine = $_);
                    $isInvalid = B_TRUE;
                    last LINE;
                }

                printf(OUTPUT "%s", $_);
                next
                    if (m/<\s*\/$columnName\s*>\s*$/s
                    || m/<\s*$columnName\/\s*>\s*$/s);

                while (<INPUT>) {

                    # dont let another tag hide behind a </COLUMN>
                    if (m/<\s*\/$columnName\s*>\s*</) {
                        chomp($errLine = $_);
                        $isInvalid = B_TRUE;
                        last LINE;
                    }

                    printf(OUTPUT "%s", $_);
                    last if (m/<\s*\/$columnName\s*>\s*$/s);
                }
            }
        }
    }

    # print trailer
    printf(OUTPUT "</UPLOAD>\n");

    if (!close(OUTPUT)) {
        $errMsg = sprintf("%s: cannot close output file '%s'\n", ECM_PREFIX, $outfile);
        EMD_PERL_ERROR($errMsg);
        last FILE;
    }

    if (!close(INPUT)) {
        $errMsg = sprintf("%s: cannot close input file '%s'\n", ECM_PREFIX, $infile);
        EMD_PERL_ERROR($errMsg);
    }

    if ($isInvalid == B_TRUE) {
        $errMsg = sprintf("%s: invalid input line '%s' in input file '%s'\n",
            ECM_PREFIX, $errLine, $infile);
        EMD_PERL_ERROR($errMsg);

        if (unlink($outfile) != 1) {
            $errMsg = sprintf("%s: cannot delete output file '%s'\n", ECM_PREFIX, $outfile);
            EMD_PERL_ERROR($errMsg);
        }

        $count--;
    }

    if (($debug_opt != 0) && ($isInvalid != B_TRUE)) {
        printf(STDOUT "%s\n", $outfile);
        rename($infile, $infile . '.old');
    }
    elsif (unlink($infile) != 1) {
        $errMsg = sprintf("%s: cannot delete input file '%s'\n", ECM_PREFIX, $infile);
        EMD_PERL_ERROR($errMsg);
    }
}
continue {
    $i++;  # bump index to check for successful collections
}


# if we have not converted at least one file, create a xxx.ext0.1 empty file
if ($count == 0) {
    $outfile = getUniqueOutput();
    open(OUTPUT, "> $outfile");
    close(OUTPUT);
}

exit(E_SUCCESS);

# --------------------- End of Program -----------------------------------
