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

package android.mtp;

import android.content.ContentProviderClient;
import android.database.Cursor;
import android.net.Uri;
import android.os.RemoteException;
import android.provider.MediaStore.Audio;
import android.provider.MediaStore.Files;
import android.provider.MediaStore.Images;
import android.util.Log;

import java.util.ArrayList;

/**
 * MtpPropertyGroup represents a list of MTP properties.
 * {@hide}
 */
class MtpPropertyGroup {
    private static final String TAG = MtpPropertyGroup.class.getSimpleName();

    private class Property {
        int code;
        int type;
        int column;

        Property(int code, int type, int column) {
            this.code = code;
            this.type = type;
            this.column = column;
        }
    }

    // list of all properties in this group
    private final Property[] mProperties;

    // list of columns for database query
    private String[] mColumns;

    private static final String PATH_WHERE = Files.FileColumns.DATA + "=?";

    // constructs a property group for a list of properties
    public MtpPropertyGroup(int[] properties) {
        int count = properties.length;
        ArrayList<String> columns = new ArrayList<>(count);
        columns.add(Files.FileColumns._ID);

        mProperties = new Property[count];
        for (int i = 0; i < count; i++) {
            mProperties[i] = createProperty(properties[i], columns);
        }
        count = columns.size();
        mColumns = new String[count];
        for (int i = 0; i < count; i++) {
            mColumns[i] = columns.get(i);
        }
    }

    private Property createProperty(int code, ArrayList<String> columns) {
        String column = null;
        int type;

        switch (code) {
            case MtpConstants.PROPERTY_STORAGE_ID:
                type = MtpConstants.TYPE_UINT32;
                break;
            case MtpConstants.PROPERTY_OBJECT_FORMAT:
                type = MtpConstants.TYPE_UINT16;
                break;
            case MtpConstants.PROPERTY_PROTECTION_STATUS:
                type = MtpConstants.TYPE_UINT16;
                break;
            case MtpConstants.PROPERTY_OBJECT_SIZE:
                type = MtpConstants.TYPE_UINT64;
                break;
            case MtpConstants.PROPERTY_OBJECT_FILE_NAME:
                type = MtpConstants.TYPE_STR;
                break;
            case MtpConstants.PROPERTY_NAME:
                type = MtpConstants.TYPE_STR;
                break;
            case MtpConstants.PROPERTY_DATE_MODIFIED:
                type = MtpConstants.TYPE_STR;
                break;
            case MtpConstants.PROPERTY_DATE_ADDED:
                type = MtpConstants.TYPE_STR;
                break;
            case MtpConstants.PROPERTY_ORIGINAL_RELEASE_DATE:
                column = Audio.AudioColumns.YEAR;
                type = MtpConstants.TYPE_STR;
                break;
            case MtpConstants.PROPERTY_PARENT_OBJECT:
                type = MtpConstants.TYPE_UINT32;
                break;
            case MtpConstants.PROPERTY_PERSISTENT_UID:
                type = MtpConstants.TYPE_UINT128;
                break;
            case MtpConstants.PROPERTY_DURATION:
                column = Audio.AudioColumns.DURATION;
                type = MtpConstants.TYPE_UINT32;
                break;
            case MtpConstants.PROPERTY_TRACK:
                column = Audio.AudioColumns.TRACK;
                type = MtpConstants.TYPE_UINT16;
                break;
            case MtpConstants.PROPERTY_DISPLAY_NAME:
                type = MtpConstants.TYPE_STR;
                break;
            case MtpConstants.PROPERTY_ARTIST:
                column = Audio.AudioColumns.ARTIST;
                type = MtpConstants.TYPE_STR;
                break;
            case MtpConstants.PROPERTY_ALBUM_NAME:
                column = Audio.AudioColumns.ALBUM;
                type = MtpConstants.TYPE_STR;
                break;
            case MtpConstants.PROPERTY_ALBUM_ARTIST:
                column = Audio.AudioColumns.ALBUM_ARTIST;
                type = MtpConstants.TYPE_STR;
                break;
            case MtpConstants.PROPERTY_GENRE:
                column = Audio.AudioColumns.GENRE;
                type = MtpConstants.TYPE_STR;
                break;
            case MtpConstants.PROPERTY_COMPOSER:
                column = Audio.AudioColumns.COMPOSER;
                type = MtpConstants.TYPE_STR;
                break;
            case MtpConstants.PROPERTY_DESCRIPTION:
                column = Images.ImageColumns.DESCRIPTION;
                type = MtpConstants.TYPE_STR;
                break;
            case MtpConstants.PROPERTY_AUDIO_WAVE_CODEC:
            case MtpConstants.PROPERTY_AUDIO_BITRATE:
            case MtpConstants.PROPERTY_SAMPLE_RATE:
                // these are special cased
                type = MtpConstants.TYPE_UINT32;
                break;
            case MtpConstants.PROPERTY_BITRATE_TYPE:
            case MtpConstants.PROPERTY_NUMBER_OF_CHANNELS:
                // these are special cased
                type = MtpConstants.TYPE_UINT16;
                break;
            default:
                type = MtpConstants.TYPE_UNDEFINED;
                Log.e(TAG, "unsupported property " + code);
                break;
        }

        if (column != null) {
            columns.add(column);
            return new Property(code, type, columns.size() - 1);
        } else {
            return new Property(code, type, -1);
        }
    }

    /**
     * Gets the values of the properties represented by this property group for the given
     * object and adds them to the given property list.
     * @return Response_OK if the operation succeeded.
     */
    public int getPropertyList(ContentProviderClient provider, String volumeName,
            MtpStorageManager.MtpObject object, MtpPropertyList list) {
        Cursor c = null;
        int id = object.getId();
        String path = object.getPath().toString();
        for (Property property : mProperties) {
            if (property.column != -1 && c == null) {
                try {
                    // Look up the entry in MediaProvider only if one of those properties is needed.
                    final Uri uri = MtpDatabase.getObjectPropertiesUri(object.getFormat(),
                            volumeName);
                    c = provider.query(uri, mColumns,
                            PATH_WHERE, new String[] {path}, null, null);
                    if (c != null && !c.moveToNext()) {
                        c.close();
                        c = null;
                    }
                } catch (IllegalArgumentException e) {
                    return MtpConstants.RESPONSE_INVALID_OBJECT_PROP_CODE;
                } catch (RemoteException e) {
                    Log.e(TAG, "Mediaprovider lookup failed");
                }
            }
            switch (property.code) {
                case MtpConstants.PROPERTY_PROTECTION_STATUS:
                    // protection status is always 0
                    list.append(id, property.code, property.type, 0);
                    break;
                case MtpConstants.PROPERTY_NAME:
                case MtpConstants.PROPERTY_OBJECT_FILE_NAME:
                case MtpConstants.PROPERTY_DISPLAY_NAME:
                    list.append(id, property.code, object.getName());
                    break;
                case MtpConstants.PROPERTY_DATE_MODIFIED:
                case MtpConstants.PROPERTY_DATE_ADDED:
                    // convert from seconds to DateTime
                    list.append(id, property.code,
                            format_date_time(object.getModifiedTime()));
                    break;
                case MtpConstants.PROPERTY_STORAGE_ID:
                    list.append(id, property.code, property.type, object.getStorageId());
                    break;
                case MtpConstants.PROPERTY_OBJECT_FORMAT:
                    list.append(id, property.code, property.type, object.getFormat());
                    break;
                case MtpConstants.PROPERTY_OBJECT_SIZE:
                    list.append(id, property.code, property.type, object.getSize());
                    break;
                case MtpConstants.PROPERTY_PARENT_OBJECT:
                    list.append(id, property.code, property.type,
                            object.getParent().isRoot() ? 0 : object.getParent().getId());
                    break;
                case MtpConstants.PROPERTY_PERSISTENT_UID:
                    // The persistent uid must be unique and never reused among all objects,
                    // and remain the same between sessions.
                    long puid = (object.getPath().toString().hashCode() << 32)
                            + object.getModifiedTime();
                    list.append(id, property.code, property.type, puid);
                    break;
                case MtpConstants.PROPERTY_ORIGINAL_RELEASE_DATE:
                    // release date is stored internally as just the year
                    int year = 0;
                    if (c != null)
                        year = c.getInt(property.column);
                    String dateTime = Integer.toString(year) + "0101T000000";
                    list.append(id, property.code, dateTime);
                    break;
                case MtpConstants.PROPERTY_TRACK:
                    int track = 0;
                    if (c != null)
                        track = c.getInt(property.column);
                    list.append(id, property.code, MtpConstants.TYPE_UINT16,
                            track % 1000);
                    break;
                case MtpConstants.PROPERTY_AUDIO_WAVE_CODEC:
                case MtpConstants.PROPERTY_AUDIO_BITRATE:
                case MtpConstants.PROPERTY_SAMPLE_RATE:
                    // we don't have these in our database, so return 0
                    list.append(id, property.code, MtpConstants.TYPE_UINT32, 0);
                    break;
                case MtpConstants.PROPERTY_BITRATE_TYPE:
                case MtpConstants.PROPERTY_NUMBER_OF_CHANNELS:
                    // we don't have these in our database, so return 0
                    list.append(id, property.code, MtpConstants.TYPE_UINT16, 0);
                    break;
                default:
                    switch(property.type) {
                        case MtpConstants.TYPE_UNDEFINED:
                            list.append(id, property.code, property.type, 0);
                            break;
                        case MtpConstants.TYPE_STR:
                            String value = "";
                            if (c != null)
                                value = c.getString(property.column);
                            list.append(id, property.code, value);
                            break;
                        default:
                            long longValue = 0L;
                            if (c != null)
                                longValue = c.getLong(property.column);
                            list.append(id, property.code, property.type, longValue);
                    }
            }
        }
        if (c != null)
            c.close();
        return MtpConstants.RESPONSE_OK;
    }

    private native String format_date_time(long seconds);
}
