/*
 * Copyright (C) 2008 Esmertec AG.
 * Copyright (C) 2008 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 com.android.im.app;

import com.android.im.plugin.ImConfigNames;
import com.android.im.provider.Imps;

import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.util.Log;
import android.util.Base64;

import java.util.Map;

public class DatabaseUtils {

    private static final String TAG = ImApp.LOG_TAG;

    private DatabaseUtils() {
    }

    public static Cursor queryAccountsForProvider(ContentResolver cr,
            String[] projection, long providerId) {
        StringBuilder where = new StringBuilder(Imps.Account.ACTIVE);
        where.append("=1 AND ").append(Imps.Account.PROVIDER).append('=').append(providerId);
        Cursor c = cr.query(Imps.Account.CONTENT_URI, projection, where.toString(), null, null);
        if (c != null && !c.moveToFirst()) {
            c.close();
            return null;
        }
        return c;
    }

    public static Drawable getAvatarFromCursor(Cursor cursor, int dataColumn) {
        byte[] rawData = cursor.getBlob(dataColumn);
        if (rawData == null) {
            return null;
        }
        return decodeAvatar(rawData);
    }

    public static Uri getAvatarUri(Uri baseUri, long providerId, long accountId) {
        Uri.Builder builder = baseUri.buildUpon();
        ContentUris.appendId(builder, providerId);
        ContentUris.appendId(builder, accountId);
        return builder.build();
    }

    public static Drawable getAvatarFromCursor(Cursor cursor, int dataColumn,
            int encodedDataColumn, String username, boolean updateBlobUseCursor,
            ContentResolver resolver, Uri updateBlobUri) {
        /**
         * Optimization: the avatar table in IM content provider have two
         * columns, one for the raw blob data, another for the base64 encoded
         * data. The reason for this is when the avatars are initially
         * downloaded, they are in the base64 encoded form, and instead of
         * base64 decode the avatars for all the buddies up front, we can just
         * simply store the encoded data in the table, and decode them on demand
         * when displaying them. Once we decode the avatar, we store the decoded
         * data as a blob, and null out the encoded column in the avatars table.
         * query the raw blob data first, if present, great; if not, query the
         * encoded data, decode it and store as the blob, and null out the
         * encoded column.
         */
        byte[] rawData = cursor.getBlob(dataColumn);

        if (rawData == null) {
            String encodedData = cursor.getString(encodedDataColumn);
            if (encodedData == null) {
                // Log.e(LogTag.LOG_TAG, "getAvatarFromCursor for " + username +
                // ", no raw or encoded data!");
                return null;
            }

            rawData = Base64.decode(encodedData, Base64.DEFAULT);

            // if (DBG) {
            // log("getAvatarFromCursor for " + username + ": found encoded
            // data,"
            // + " update blob with data, len=" + rawData.length);
            // }

            if (updateBlobUseCursor) {
                cursor.updateBlob(dataColumn, rawData);
                cursor.updateString(encodedDataColumn, null);
                cursor.commitUpdates();
            } else {
                updateAvatarBlob(resolver, updateBlobUri, rawData, username);
            }
        }

        return decodeAvatar(rawData);
    }

    private static void updateAvatarBlob(ContentResolver resolver, Uri updateUri, byte[] data,
            String username) {
        ContentValues values = new ContentValues(3);
        values.put(Imps.Avatars.DATA, data);

        StringBuilder buf = new StringBuilder(Imps.Avatars.CONTACT);
        buf.append("=?");

        String[] selectionArgs = new String[] {
            username
        };

        resolver.update(updateUri, values, buf.toString(), selectionArgs);
    }

    private static Drawable decodeAvatar(byte[] data) {
        Bitmap b = BitmapFactory.decodeByteArray(data, 0, data.length);
        Drawable avatar = new BitmapDrawable(b);
        return avatar;
    }

    /**
     * Update IM provider database for a plugin using newly loaded information.
     * @param cr the resolver
     * @param providerName the plugin provider name
     * @param providerFullName the full name
     * @param signUpUrl the plugin's service signup URL
     * @param config the plugin's settings
     * @return the provider ID of the plugin
     */
    public static long updateProviderDb(ContentResolver cr,
            String providerName, String providerFullName, String signUpUrl,
            Map<String, String> config) {
        boolean versionChanged;

        // query provider data
        long providerId = Imps.Provider.getProviderIdForName(cr, providerName);
        if (providerId > 0) {
            // already loaded, check if version changed
            String pluginVersion = config.get(ImConfigNames.PLUGIN_VERSION);
            if (!isPluginVersionChanged(cr, providerId, pluginVersion)) {
                // no change, just return
                return providerId;
            }
            // changed, update provider meta data
            updateProviderRow(cr, providerId, providerFullName, signUpUrl);
            // clear branding resource map cache
            clearBrandingResourceMapCache(cr, providerId);

            Log.d(TAG, "Plugin " + providerName + "(" + providerId +
                    ") has a version change. Database updated.");
        } else {
            // new plugin, not loaded before, insert the provider data
            providerId = insertProviderRow(cr, providerName, providerFullName, signUpUrl);

            Log.d(TAG, "Plugin " + providerName + "(" + providerId +
                    ") is new. Provider added to IM db.");
        }

        // plugin provider has been inserted/updated, we need to update settings
        saveProviderSettings(cr, providerId, config);

        return providerId;
    }

    /**
     * Clear the branding resource map cache.
     */
    private static int clearBrandingResourceMapCache(ContentResolver cr, long providerId) {
        StringBuilder where = new StringBuilder();
        where.append(Imps.BrandingResourceMapCache.PROVIDER_ID);
        where.append('=');
        where.append(providerId);
        return cr.delete(Imps.BrandingResourceMapCache.CONTENT_URI, where.toString(), null);
    }

    /**
     * Insert the plugin settings into the database.
     */
    private static int saveProviderSettings(ContentResolver cr, long providerId,
            Map<String, String> config) {
        ContentValues[] settingValues = new ContentValues[config.size()];
        int index = 0;
        for (Map.Entry<String, String> entry : config.entrySet()) {
            ContentValues settingValue = new ContentValues();
            settingValue.put(Imps.ProviderSettings.PROVIDER, providerId);
            settingValue.put(Imps.ProviderSettings.NAME, entry.getKey());
            settingValue.put(Imps.ProviderSettings.VALUE, entry.getValue());
            settingValues[index++] = settingValue;
        }
        return cr.bulkInsert(Imps.ProviderSettings.CONTENT_URI, settingValues);
    }

    /**
     * Insert a new plugin provider to the provider table.
     */
    private static long insertProviderRow(ContentResolver cr, String providerName,
            String providerFullName, String signUpUrl) {
        ContentValues values = new ContentValues(3);
        values.put(Imps.Provider.NAME, providerName);
        values.put(Imps.Provider.FULLNAME, providerFullName);
        values.put(Imps.Provider.CATEGORY, ImApp.IMPS_CATEGORY);
        values.put(Imps.Provider.SIGNUP_URL, signUpUrl);
        Uri result = cr.insert(Imps.Provider.CONTENT_URI, values);
        return ContentUris.parseId(result);
    }

    /**
     * Update the data of a plugin provider.
     */
    private static int updateProviderRow(ContentResolver cr, long providerId,
            String providerFullName, String signUpUrl) {
        // Update the full name, signup url and category each time when the plugin change
        // instead of specific version change because this is called only once.
        // It's ok to update them even the values are not changed.
        // Note that we don't update the provider name because it's used as
        // identifier at some place and the plugin should never change it.
        ContentValues values = new ContentValues(3);
        values.put(Imps.Provider.FULLNAME, providerFullName);
        values.put(Imps.Provider.SIGNUP_URL, signUpUrl);
        values.put(Imps.Provider.CATEGORY, ImApp.IMPS_CATEGORY);
        Uri uri = ContentUris.withAppendedId(Imps.Provider.CONTENT_URI, providerId);
        return cr.update(uri, values, null, null);
    }

    /**
     * Compare the saved version of a plugin provider with the newly loaded version.
     */
    private static boolean isPluginVersionChanged(ContentResolver cr, long providerId,
            String newVersion) {
        String oldVersion = Imps.ProviderSettings.getStringValue(cr, providerId,
                ImConfigNames.PLUGIN_VERSION);
        if (oldVersion == null) {
            return true;
        }
        return !oldVersion.equals(newVersion);
    }
}
