/*
 * 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.
 */

#define LOG_TAG "MtpProperty"

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

namespace android {

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(-1), // disable multiple properties in GetObjectPropList for now
        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:
                LOGE("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) {
    bool deviceProp = isDeviceProperty();

    mCode = packet.getUInt16();
    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:
            LOGE("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:
                    LOGE("unsupported type for MtpProperty::setEnum");
                    break;
        }
    }
}

void MtpProperty::print() {
    LOGV("MtpProperty %04X\n", mCode);
    LOGV("    type %04X\n", mType);
    LOGV("    writeable %s\n", (mWriteable ? "true" : "false"));
}

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:
            LOGE("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:
            LOGE("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]);
}

}  // namespace android
