/*###############################################################################
# Linux Management Providers (LMP), System Memory provider package
# Copyright (C) 2008 Guillaume BOTTEX, ETRI <guillaumebottex@etri.re.kr, guillaumebottex@gmail.com>
#
# This program is being developed under the "OpenDRIM" project.
# The "OpenDRIM" project web page: http://opendrim.sourceforge.net
# The "OpenDRIM" project mailing list: opendrim@googlegroups.com
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; version 2
# of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
#################################################################################

#################################################################################
# To contributors, please leave your contact information in this section
# AND comment your changes in the source code.
#
# Modified by <Author(s)>, <Affiliation>, <Year>
###############################################################################*/

#include "cmpiOpenDRIM_Memory.h"
#include "OpenDRIM_MemoryAccess.h"

#include <iostream>

#define ToString(name, value, condition) os << (string) "      " + name + (string) "="; instance.condition ? os << "NULL" : os << instance.value; os << endl
#define ToStringInt(name, value, condition) os << (string) "      " + name + (string) "="; instance.condition ? os << "NULL" : os << (long) instance.value; os << endl
#define ToStringRef(name, value, condition) os << (string) "      " + name + (string) "="; instance.condition ? os << "NULL" : os << instance.value.toString(); os << endl
#define ToStringArray(name, value, condition) os << (string) "      " + name + (string) "=["; for (size_t i = 0; i < instance.value.size(); i++) { os << instance.value[i]; if (i < instance.value.size()-1) os << ","; } os << "]" << endl
#define ToStringArrayInt(name, value, condition) os << (string) "      " + name + (string) "=["; for (size_t i = 0; i < instance.value.size(); i++) { os << (long) instance.value[i]; if (i < instance.value.size()-1) os << ","; } os << "]" << endl
#define ToStringRefArray(name, value, condition) os << (string) "      " + name + (string) "=["; for (size_t i = 0; i < instance.value.size(); i++) { os << instance.value[i].toString(); if (i < instance.value.size()-1) os << ","; } os << "]" << endl

ostream& operator<<(ostream& os, OpenDRIM_Memory& instance) {
	os << "   [OpenDRIM_Memory]" << endl;
	ToString("Caption", Caption, Caption_isNULL);
	ToString("Description", Description, Description_isNULL);
	ToString("ElementName", ElementName, ElementName_isNULL);
	ToString("InstallDate", InstallDate, InstallDate_isNULL);
	ToStringArrayInt("OperationalStatus", OperationalStatus, OperationalStatus_isNULL);
	ToStringArray("StatusDescriptions", StatusDescriptions, StatusDescriptions_isNULL);
	ToString("Status", Status, Status_isNULL);
	ToStringInt("HealthState", HealthState, HealthState_isNULL);
	ToStringInt("PrimaryStatus", PrimaryStatus, PrimaryStatus_isNULL);
	ToStringInt("DetailedStatus", DetailedStatus, DetailedStatus_isNULL);
	ToStringInt("OperatingStatus", OperatingStatus, OperatingStatus_isNULL);
	ToStringInt("CommunicationStatus", CommunicationStatus, CommunicationStatus_isNULL);
	ToStringInt("EnabledState", EnabledState, EnabledState_isNULL);
	ToString("OtherEnabledState", OtherEnabledState, OtherEnabledState_isNULL);
	ToStringInt("RequestedState", RequestedState, RequestedState_isNULL);
	ToStringInt("EnabledDefault", EnabledDefault, EnabledDefault_isNULL);
	ToString("TimeOfLastStateChange", TimeOfLastStateChange, TimeOfLastStateChange_isNULL);
	ToStringArrayInt("AvailableRequestedStates", AvailableRequestedStates, AvailableRequestedStates_isNULL);
	ToStringInt("TransitioningToState", TransitioningToState, TransitioningToState_isNULL);
	ToString("SystemCreationClassName", SystemCreationClassName, SystemCreationClassName_isNULL);
	ToString("SystemName", SystemName, SystemName_isNULL);
	ToString("CreationClassName", CreationClassName, CreationClassName_isNULL);
	ToString("DeviceID", DeviceID, DeviceID_isNULL);
	ToString("PowerManagementSupported", PowerManagementSupported, PowerManagementSupported_isNULL);
	ToStringArrayInt("PowerManagementCapabilities", PowerManagementCapabilities, PowerManagementCapabilities_isNULL);
	ToStringInt("Availability", Availability, Availability_isNULL);
	ToStringInt("StatusInfo", StatusInfo, StatusInfo_isNULL);
	ToString("LastErrorCode", LastErrorCode, LastErrorCode_isNULL);
	ToString("ErrorDescription", ErrorDescription, ErrorDescription_isNULL);
	ToString("ErrorCleared", ErrorCleared, ErrorCleared_isNULL);
	ToStringArray("OtherIdentifyingInfo", OtherIdentifyingInfo, OtherIdentifyingInfo_isNULL);
	ToString("PowerOnHours", PowerOnHours, PowerOnHours_isNULL);
	ToString("TotalPowerOnHours", TotalPowerOnHours, TotalPowerOnHours_isNULL);
	ToStringArray("IdentifyingDescriptions", IdentifyingDescriptions, IdentifyingDescriptions_isNULL);
	ToStringArrayInt("AdditionalAvailability", AdditionalAvailability, AdditionalAvailability_isNULL);
	ToString("MaxQuiesceTime", MaxQuiesceTime, MaxQuiesceTime_isNULL);
	ToStringInt("LocationIndicator", LocationIndicator, LocationIndicator_isNULL);
	ToStringInt("DataOrganization", DataOrganization, DataOrganization_isNULL);
	ToString("Purpose", Purpose, Purpose_isNULL);
	ToStringInt("Access", Access, Access_isNULL);
	ToString("BlockSize", BlockSize, BlockSize_isNULL);
	ToString("NumberOfBlocks", NumberOfBlocks, NumberOfBlocks_isNULL);
	ToString("ConsumableBlocks", ConsumableBlocks, ConsumableBlocks_isNULL);
	ToString("IsBasedOnUnderlyingRedundancy", IsBasedOnUnderlyingRedundancy, IsBasedOnUnderlyingRedundancy_isNULL);
	ToString("SequentialAccess", SequentialAccess, SequentialAccess_isNULL);
	ToStringArrayInt("ExtentStatus", ExtentStatus, ExtentStatus_isNULL);
	ToString("NoSinglePointOfFailure", NoSinglePointOfFailure, NoSinglePointOfFailure_isNULL);
	ToStringInt("DataRedundancy", DataRedundancy, DataRedundancy_isNULL);
	ToStringInt("PackageRedundancy", PackageRedundancy, PackageRedundancy_isNULL);
	ToStringInt("DeltaReservation", DeltaReservation, DeltaReservation_isNULL);
	ToString("Primordial", Primordial, Primordial_isNULL);
	ToString("Name", Name, Name_isNULL);
	ToStringInt("NameFormat", NameFormat, NameFormat_isNULL);
	ToStringInt("NameNamespace", NameNamespace, NameNamespace_isNULL);
	ToString("OtherNameNamespace", OtherNameNamespace, OtherNameNamespace_isNULL);
	ToString("OtherNameFormat", OtherNameFormat, OtherNameFormat_isNULL);
	ToStringInt("Usage", Usage, Usage_isNULL);
	ToString("OtherUsageDescription", OtherUsageDescription, OtherUsageDescription_isNULL);
	ToStringArrayInt("ClientSettableUsage", ClientSettableUsage, ClientSettableUsage_isNULL);
	ToString("Volatile", Volatile, Volatile_isNULL);
	ToString("ErrorMethodology", ErrorMethodology, ErrorMethodology_isNULL);
	ToString("StartingAddress", StartingAddress, StartingAddress_isNULL);
	ToString("EndingAddress", EndingAddress, EndingAddress_isNULL);
	ToStringInt("ErrorInfo", ErrorInfo, ErrorInfo_isNULL);
	ToString("OtherErrorDescription", OtherErrorDescription, OtherErrorDescription_isNULL);
	ToString("CorrectableError", CorrectableError, CorrectableError_isNULL);
	ToString("ErrorTime", ErrorTime, ErrorTime_isNULL);
	ToStringInt("ErrorAccess", ErrorAccess, ErrorAccess_isNULL);
	ToString("ErrorTransferSize", ErrorTransferSize, ErrorTransferSize_isNULL);
	ToStringArrayInt("ErrorData", ErrorData, ErrorData_isNULL);
	ToStringInt("ErrorDataOrder", ErrorDataOrder, ErrorDataOrder_isNULL);
	ToString("ErrorAddress", ErrorAddress, ErrorAddress_isNULL);
	ToString("SystemLevelAddress", SystemLevelAddress, SystemLevelAddress_isNULL);
	ToString("ErrorResolution", ErrorResolution, ErrorResolution_isNULL);
	ToStringArrayInt("AdditionalErrorData", AdditionalErrorData, AdditionalErrorData_isNULL);
	os << "   [\\OpenDRIM_Memory]" << endl;
	return os;
}

int main() {
	
	string errorMessage;

	int errorCode = SystemMemory_OpenDRIM_Memory_load(NULL, errorMessage);
	if (errorCode != OK) {
		cout << "ERROR " << errorCode << ": " << errorMessage << endl;
		return -1;
	}

	cout << endl << "[enumInstances]" << endl;
	vector<OpenDRIM_Memory> instances;
	
	errorCode = SystemMemory_OpenDRIM_Memory_retrieve(NULL, NULL, instances, NULL, errorMessage, "ei");
	if (errorCode != OK) {
		cout << "ERROR " << errorCode << ": " << errorMessage << endl;
		return -1;
	}
	
	vector<OpenDRIM_Memory>::iterator it = instances.begin();
	for (; it != instances.end(); ++it) {
		cout << *it;
	}
	
	cout << "[\\enumInstances]" << endl;
	cout << endl << "[enumInstanceNames & getInstance]" << endl;
	
	instances.clear();
	errorCode = SystemMemory_OpenDRIM_Memory_retrieve(NULL, NULL, instances, NULL, errorMessage, "ein");
	if (errorCode != OK) {
		cout << "ERROR " << errorCode << ": " << errorMessage << endl;
		return -1;
	}
	
	it = instances.begin();
	for (; it != instances.end(); ++it) {
		errorCode = SystemMemory_OpenDRIM_Memory_getInstance(NULL, NULL, *it, NULL, errorMessage);
		if (errorCode != OK) {
			cout << "ERROR " << errorCode << ": " << errorMessage << endl;
			return -1;
		}
		cout << *it;
	}
	
	cout << "[\\enumInstanceNames & getInstance]" << endl;
	cout << endl;

	errorCode = SystemMemory_OpenDRIM_Memory_unload(errorMessage);
	if (errorCode != OK) {
		cout << "ERROR " << errorCode << ": " << errorMessage << endl;
		return -1;
	}
	return 0;
}
