/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *	  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Copyright (C) 2014 TeamWin - bigbiff and Dees_Troy mtp database conversion to C++
 */

#include "MtpDataPacket.h"
#include "MtpDebug.h"
#include "MtpProperty.h"
#include "MtpStringBuffer.h"
#include "MtpUtils.h"

MtpProperty::MtpProperty()
	:	mCode(0),
		mType(0),
		mWriteable(false),
		mDefaultArrayLength(0),
		mDefaultArrayValues(NULL),
		mCurrentArrayLength(0),
		mCurrentArrayValues(NULL),
		mGroupCode(0),
		mFormFlag(kFormNone),
		mEnumLength(0),
		mEnumValues(NULL)
{
	memset(&mDefaultValue, 0, sizeof(mDefaultValue));
	memset(&mCurrentValue, 0, sizeof(mCurrentValue));
	memset(&mMinimumValue, 0, sizeof(mMinimumValue));
	memset(&mMaximumValue, 0, sizeof(mMaximumValue));
}

MtpProperty::MtpProperty(MtpPropertyCode propCode,
						 MtpDataType type,
						 bool writeable,
						 int defaultValue)
	:   mCode(propCode),
		mType(type),
		mWriteable(writeable),
		mDefaultArrayLength(0),
		mDefaultArrayValues(NULL),
		mCurrentArrayLength(0),
		mCurrentArrayValues(NULL),
		mGroupCode(0),
		mFormFlag(kFormNone),
		mEnumLength(0),
		mEnumValues(NULL)
{
	memset(&mDefaultValue, 0, sizeof(mDefaultValue));
	memset(&mCurrentValue, 0, sizeof(mCurrentValue));
	memset(&mMinimumValue, 0, sizeof(mMinimumValue));
	memset(&mMaximumValue, 0, sizeof(mMaximumValue));

	if (defaultValue) {
		switch (type) {
			case MTP_TYPE_INT8:
				mDefaultValue.u.i8 = defaultValue;
				break;
			case MTP_TYPE_UINT8:
				mDefaultValue.u.u8 = defaultValue;
				break;
			case MTP_TYPE_INT16:
				mDefaultValue.u.i16 = defaultValue;
				break;
			case MTP_TYPE_UINT16:
				mDefaultValue.u.u16 = defaultValue;
				break;
			case MTP_TYPE_INT32:
				mDefaultValue.u.i32 = defaultValue;
				break;
			case MTP_TYPE_UINT32:
				mDefaultValue.u.u32 = defaultValue;
				break;
			case MTP_TYPE_INT64:
				mDefaultValue.u.i64 = defaultValue;
				break;
			case MTP_TYPE_UINT64:
				mDefaultValue.u.u64 = defaultValue;
				break;
			default:
				MTPE("unknown type %04X in MtpProperty::MtpProperty", type);
		}
	}
}

MtpProperty::~MtpProperty() {
	if (mType == MTP_TYPE_STR) {
		// free all strings
		free(mDefaultValue.str);
		free(mCurrentValue.str);
		free(mMinimumValue.str);
		free(mMaximumValue.str);
		if (mDefaultArrayValues) {
			for (int i = 0; i < mDefaultArrayLength; i++)
				free(mDefaultArrayValues[i].str);
		}
		if (mCurrentArrayValues) {
			for (int i = 0; i < mCurrentArrayLength; i++)
				free(mCurrentArrayValues[i].str);
		}
		if (mEnumValues) {
			for (int i = 0; i < mEnumLength; i++)
				free(mEnumValues[i].str);
		}
	}
	delete[] mDefaultArrayValues;
	delete[] mCurrentArrayValues;
	delete[] mEnumValues;
}

void MtpProperty::read(MtpDataPacket& packet) {
	mCode = packet.getUInt16();
	bool deviceProp = isDeviceProperty();
	mType = packet.getUInt16();
	mWriteable = (packet.getUInt8() == 1);
	switch (mType) {
		case MTP_TYPE_AINT8:
		case MTP_TYPE_AUINT8:
		case MTP_TYPE_AINT16:
		case MTP_TYPE_AUINT16:
		case MTP_TYPE_AINT32:
		case MTP_TYPE_AUINT32:
		case MTP_TYPE_AINT64:
		case MTP_TYPE_AUINT64:
		case MTP_TYPE_AINT128:
		case MTP_TYPE_AUINT128:
			mDefaultArrayValues = readArrayValues(packet, mDefaultArrayLength);
			if (deviceProp)
				mCurrentArrayValues = readArrayValues(packet, mCurrentArrayLength);
			break;
		default:
			readValue(packet, mDefaultValue);
			if (deviceProp)
				readValue(packet, mCurrentValue);
	}
	if (!deviceProp)
		mGroupCode = packet.getUInt32();
	mFormFlag = packet.getUInt8();

	if (mFormFlag == kFormRange) {
			readValue(packet, mMinimumValue);
			readValue(packet, mMaximumValue);
			readValue(packet, mStepSize);
	} else if (mFormFlag == kFormEnum) {
		mEnumLength = packet.getUInt16();
		mEnumValues = new MtpPropertyValue[mEnumLength];
		for (int i = 0; i < mEnumLength; i++)
			readValue(packet, mEnumValues[i]);
	}
}

void MtpProperty::write(MtpDataPacket& packet) {
	bool deviceProp = isDeviceProperty();

	packet.putUInt16(mCode);
	packet.putUInt16(mType);
	packet.putUInt8(mWriteable ? 1 : 0);

	switch (mType) {
		case MTP_TYPE_AINT8:
		case MTP_TYPE_AUINT8:
		case MTP_TYPE_AINT16:
		case MTP_TYPE_AUINT16:
		case MTP_TYPE_AINT32:
		case MTP_TYPE_AUINT32:
		case MTP_TYPE_AINT64:
		case MTP_TYPE_AUINT64:
		case MTP_TYPE_AINT128:
		case MTP_TYPE_AUINT128:
			writeArrayValues(packet, mDefaultArrayValues, mDefaultArrayLength);
			if (deviceProp)
				writeArrayValues(packet, mCurrentArrayValues, mCurrentArrayLength);
			break;
		default:
			writeValue(packet, mDefaultValue);
			if (deviceProp)
				writeValue(packet, mCurrentValue);
	}
	packet.putUInt32(mGroupCode);
	if (!deviceProp)
		packet.putUInt8(mFormFlag);
	if (mFormFlag == kFormRange) {
			writeValue(packet, mMinimumValue);
			writeValue(packet, mMaximumValue);
			writeValue(packet, mStepSize);
	} else if (mFormFlag == kFormEnum) {
		packet.putUInt16(mEnumLength);
		for (int i = 0; i < mEnumLength; i++)
			writeValue(packet, mEnumValues[i]);
	}
}

void MtpProperty::setDefaultValue(const uint16_t* string) {
	free(mDefaultValue.str);
	if (string) {
		MtpStringBuffer buffer(string);
		mDefaultValue.str = strdup(buffer);
	}
	else
		mDefaultValue.str = NULL;
}

void MtpProperty::setCurrentValue(const uint16_t* string) {
	free(mCurrentValue.str);
	if (string) {
		MtpStringBuffer buffer(string);
		mCurrentValue.str = strdup(buffer);
	}
	else
		mCurrentValue.str = NULL;
}

void MtpProperty::setFormRange(int min, int max, int step) {
	mFormFlag = kFormRange;
	switch (mType) {
		case MTP_TYPE_INT8:
			mMinimumValue.u.i8 = min;
			mMaximumValue.u.i8 = max;
			mStepSize.u.i8 = step;
			break;
		case MTP_TYPE_UINT8:
			mMinimumValue.u.u8 = min;
			mMaximumValue.u.u8 = max;
			mStepSize.u.u8 = step;
			break;
		case MTP_TYPE_INT16:
			mMinimumValue.u.i16 = min;
			mMaximumValue.u.i16 = max;
			mStepSize.u.i16 = step;
			break;
		case MTP_TYPE_UINT16:
			mMinimumValue.u.u16 = min;
			mMaximumValue.u.u16 = max;
			mStepSize.u.u16 = step;
			break;
		case MTP_TYPE_INT32:
			mMinimumValue.u.i32 = min;
			mMaximumValue.u.i32 = max;
			mStepSize.u.i32 = step;
			break;
		case MTP_TYPE_UINT32:
			mMinimumValue.u.u32 = min;
			mMaximumValue.u.u32 = max;
			mStepSize.u.u32 = step;
			break;
		case MTP_TYPE_INT64:
			mMinimumValue.u.i64 = min;
			mMaximumValue.u.i64 = max;
			mStepSize.u.i64 = step;
			break;
		case MTP_TYPE_UINT64:
			mMinimumValue.u.u64 = min;
			mMaximumValue.u.u64 = max;
			mStepSize.u.u64 = step;
			break;
		default:
			MTPE("unsupported type for MtpProperty::setRange");
			break;
	}
}

void MtpProperty::setFormEnum(const int* values, int count) {
	 mFormFlag = kFormEnum;
	 delete[] mEnumValues;
	 mEnumValues = new MtpPropertyValue[count];
	 mEnumLength = count;

	for (int i = 0; i < count; i++) {
		int value = *values++;
			switch (mType) {
				case MTP_TYPE_INT8:
					mEnumValues[i].u.i8 = value;
					break;
				case MTP_TYPE_UINT8:
					mEnumValues[i].u.u8 = value;
					break;
				case MTP_TYPE_INT16:
					mEnumValues[i].u.i16 = value;
					break;
				case MTP_TYPE_UINT16:
					mEnumValues[i].u.u16 = value;
					break;
				case MTP_TYPE_INT32:
					mEnumValues[i].u.i32 = value;
					break;
				case MTP_TYPE_UINT32:
					mEnumValues[i].u.u32 = value;
					break;
				case MTP_TYPE_INT64:
					mEnumValues[i].u.i64 = value;
					break;
				case MTP_TYPE_UINT64:
					mEnumValues[i].u.u64 = value;
					break;
				default:
					MTPE("unsupported type for MtpProperty::setEnum");
					break;
		}
	}
}

void MtpProperty::setFormDateTime() {
	 mFormFlag = kFormDateTime;
}

void MtpProperty::print() {
	MtpString buffer;
	bool deviceProp = isDeviceProperty();
	if (deviceProp)
		MTPI("	%s (%04X)", MtpDebug::getDevicePropCodeName(mCode), mCode);
	else
		MTPI("	%s (%04X)", MtpDebug::getObjectPropCodeName(mCode), mCode);
	MTPI("	type %04X", mType);
	MTPI("	writeable %s", (mWriteable ? "true" : "false"));
	buffer = "	default value: ";
	print(mDefaultValue, buffer);
	MTPI("%s", (const char *)buffer);
	if (deviceProp) {
		buffer = "	current value: ";
		print(mCurrentValue, buffer);
		MTPI("%s", (const char *)buffer);
	}
	switch (mFormFlag) {
		case kFormNone:
			break;
		case kFormRange:
			buffer = "	Range (";
			print(mMinimumValue, buffer);
			buffer += ", ";
			print(mMaximumValue, buffer);
			buffer += ", ";
			print(mStepSize, buffer);
			buffer += ")";
			MTPI("%s", (const char *)buffer);
			break;
		case kFormEnum:
			buffer = "	Enum { ";
			for (int i = 0; i < mEnumLength; i++) {
				print(mEnumValues[i], buffer);
				buffer += " ";
			}
			buffer += "}";
			MTPI("%s", (const char *)buffer);
			break;
		case kFormDateTime:
			MTPI("	DateTime\n");
			break;
		default:
			MTPI("	form %d\n", mFormFlag);
			break;
	}
}

void MtpProperty::print(MtpPropertyValue& value, MtpString& buffer) {
	switch (mType) {
		case MTP_TYPE_INT8:
			buffer.appendFormat("%d", value.u.i8);
			break;
		case MTP_TYPE_UINT8:
			buffer.appendFormat("%d", value.u.u8);
			break;
		case MTP_TYPE_INT16:
			buffer.appendFormat("%d", value.u.i16);
			break;
		case MTP_TYPE_UINT16:
			buffer.appendFormat("%d", value.u.u16);
			break;
		case MTP_TYPE_INT32:
			buffer.appendFormat("%d", value.u.i32);
			break;
		case MTP_TYPE_UINT32:
			buffer.appendFormat("%d", value.u.u32);
			break;
		case MTP_TYPE_INT64:
			buffer.appendFormat("%lld", value.u.i64);
			break;
		case MTP_TYPE_UINT64:
			buffer.appendFormat("%lld", value.u.u64);
			break;
		case MTP_TYPE_INT128:
			buffer.appendFormat("%08X%08X%08X%08X", value.u.i128[0], value.u.i128[1],
					value.u.i128[2], value.u.i128[3]);
			break;
		case MTP_TYPE_UINT128:
			buffer.appendFormat("%08X%08X%08X%08X", value.u.u128[0], value.u.u128[1],
					value.u.u128[2], value.u.u128[3]);
			break;
		case MTP_TYPE_STR:
			buffer.appendFormat("%s", value.str);
			break;
		default:
			MTPE("unsupported type for MtpProperty::print\n");
			break;
	}
}

void MtpProperty::readValue(MtpDataPacket& packet, MtpPropertyValue& value) {
	MtpStringBuffer stringBuffer;

	switch (mType) {
		case MTP_TYPE_INT8:
		case MTP_TYPE_AINT8:
			value.u.i8 = packet.getInt8();
			break;
		case MTP_TYPE_UINT8:
		case MTP_TYPE_AUINT8:
			value.u.u8 = packet.getUInt8();
			break;
		case MTP_TYPE_INT16:
		case MTP_TYPE_AINT16:
			value.u.i16 = packet.getInt16();
			break;
		case MTP_TYPE_UINT16:
		case MTP_TYPE_AUINT16:
			value.u.u16 = packet.getUInt16();
			break;
		case MTP_TYPE_INT32:
		case MTP_TYPE_AINT32:
			value.u.i32 = packet.getInt32();
			break;
		case MTP_TYPE_UINT32:
		case MTP_TYPE_AUINT32:
			value.u.u32 = packet.getUInt32();
			break;
		case MTP_TYPE_INT64:
		case MTP_TYPE_AINT64:
			value.u.i64 = packet.getInt64();
			break;
		case MTP_TYPE_UINT64:
		case MTP_TYPE_AUINT64:
			value.u.u64 = packet.getUInt64();
			break;
		case MTP_TYPE_INT128:
		case MTP_TYPE_AINT128:
			packet.getInt128(value.u.i128);
			break;
		case MTP_TYPE_UINT128:
		case MTP_TYPE_AUINT128:
			packet.getUInt128(value.u.u128);
			break;
		case MTP_TYPE_STR:
			packet.getString(stringBuffer);
			value.str = strdup(stringBuffer);
			break;
		default:
			MTPE("unknown type %04X in MtpProperty::readValue", mType);
	}
}

void MtpProperty::writeValue(MtpDataPacket& packet, MtpPropertyValue& value) {
	MtpStringBuffer stringBuffer;

	switch (mType) {
		case MTP_TYPE_INT8:
		case MTP_TYPE_AINT8:
			packet.putInt8(value.u.i8);
			break;
		case MTP_TYPE_UINT8:
		case MTP_TYPE_AUINT8:
			packet.putUInt8(value.u.u8);
			break;
		case MTP_TYPE_INT16:
		case MTP_TYPE_AINT16:
			packet.putInt16(value.u.i16);
			break;
		case MTP_TYPE_UINT16:
		case MTP_TYPE_AUINT16:
			packet.putUInt16(value.u.u16);
			break;
		case MTP_TYPE_INT32:
		case MTP_TYPE_AINT32:
			packet.putInt32(value.u.i32);
			break;
		case MTP_TYPE_UINT32:
		case MTP_TYPE_AUINT32:
			packet.putUInt32(value.u.u32);
			break;
		case MTP_TYPE_INT64:
		case MTP_TYPE_AINT64:
			packet.putInt64(value.u.i64);
			break;
		case MTP_TYPE_UINT64:
		case MTP_TYPE_AUINT64:
			packet.putUInt64(value.u.u64);
			break;
		case MTP_TYPE_INT128:
		case MTP_TYPE_AINT128:
			packet.putInt128(value.u.i128);
			break;
		case MTP_TYPE_UINT128:
		case MTP_TYPE_AUINT128:
			packet.putUInt128(value.u.u128);
			break;
		case MTP_TYPE_STR:
			if (value.str)
				packet.putString(value.str);
			else
				packet.putEmptyString();
			break;
		default:
			MTPE("unknown type %04X in MtpProperty::writeValue", mType);
	}
}

MtpPropertyValue* MtpProperty::readArrayValues(MtpDataPacket& packet, int& length) {
	length = packet.getUInt32();
	if (length == 0)
		return NULL;
	MtpPropertyValue* result = new MtpPropertyValue[length];
	for (int i = 0; i < length; i++)
		readValue(packet, result[i]);
	return result;
}

void MtpProperty::writeArrayValues(MtpDataPacket& packet, MtpPropertyValue* values, int length) {
	packet.putUInt32(length);
	for (int i = 0; i < length; i++)
		writeValue(packet, values[i]);
}

