/*
 * Copyright (C) 2009 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.providers.userdictionary;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;
import java.util.zip.CRC32;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

import android.backup.BackupDataInput;
import android.backup.BackupDataOutput;
import android.backup.BackupHelperAgent;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.provider.UserDictionary.Words;
import android.text.TextUtils;
import android.util.Log;

/**
 * Performs backup and restore of the User Dictionary.
 */
public class DictionaryBackupAgent extends BackupHelperAgent {

    private static final String KEY_DICTIONARY = "userdictionary";

    private static final int STATE_DICTIONARY = 0;
    private static final int STATE_SIZE = 1;

    private static final String SEPARATOR = "|";

    private static final byte[] EMPTY_DATA = new byte[0];

    private static final String TAG = "DictionaryBackupAgent";

    private static final int COLUMN_WORD = 1;
    private static final int COLUMN_FREQUENCY = 2;
    private static final int COLUMN_LOCALE = 3;
    private static final int COLUMN_APPID = 4;

    private static final String[] PROJECTION = {
        Words._ID,
        Words.WORD,
        Words.FREQUENCY,
        Words.LOCALE,
        Words.APP_ID
    };

    @Override
    public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
            ParcelFileDescriptor newState) throws IOException {

        byte[] userDictionaryData = getDictionary();

        long[] stateChecksums = readOldChecksums(oldState);

        stateChecksums[STATE_DICTIONARY] =
                writeIfChanged(stateChecksums[STATE_DICTIONARY], KEY_DICTIONARY,
                        userDictionaryData, data);

        writeNewChecksums(stateChecksums, newState);
    }

    @Override
    public void onRestore(BackupDataInput data, int appVersionCode,
            ParcelFileDescriptor newState) throws IOException {

        while (data.readNextHeader()) {
            final String key = data.getKey();
            final int size = data.getDataSize();
            if (KEY_DICTIONARY.equals(key)) {
                restoreDictionary(data, Words.CONTENT_URI);
            } else {
                data.skipEntityData();
            }
        }
    }

    private long[] readOldChecksums(ParcelFileDescriptor oldState) throws IOException {
        long[] stateChecksums = new long[STATE_SIZE];

        DataInputStream dataInput = new DataInputStream(
                new FileInputStream(oldState.getFileDescriptor()));
        for (int i = 0; i < STATE_SIZE; i++) {
            try {
                stateChecksums[i] = dataInput.readLong();
            } catch (EOFException eof) {
                break;
            }
        }
        dataInput.close();
        return stateChecksums;
    }

    private void writeNewChecksums(long[] checksums, ParcelFileDescriptor newState)
            throws IOException {
        DataOutputStream dataOutput = new DataOutputStream(
                new FileOutputStream(newState.getFileDescriptor()));
        for (int i = 0; i < STATE_SIZE; i++) {
            dataOutput.writeLong(checksums[i]);
        }
        dataOutput.close();
    }

    private long writeIfChanged(long oldChecksum, String key, byte[] data,
            BackupDataOutput output) {
        CRC32 checkSummer = new CRC32();
        checkSummer.update(data);
        long newChecksum = checkSummer.getValue();
        if (oldChecksum == newChecksum) {
            return oldChecksum;
        }
        try {
            output.writeEntityHeader(key, data.length);
            output.writeEntityData(data, data.length);
        } catch (IOException ioe) {
            // Bail
        }
        return newChecksum;
    }

    private byte[] getDictionary() {
        Cursor cursor = getContentResolver().query(Words.CONTENT_URI, PROJECTION,
                null, null, Words.WORD);
        if (cursor == null) return EMPTY_DATA;
        if (!cursor.moveToFirst()) {
            Log.e(TAG, "Couldn't read from the cursor");
            cursor.close();
            return EMPTY_DATA;
        }
        byte[] sizeBytes = new byte[4];
        ByteArrayOutputStream baos = new ByteArrayOutputStream(cursor.getCount() * 10);
        try {
            GZIPOutputStream gzip = new GZIPOutputStream(baos);
            while (!cursor.isAfterLast()) {
                String name = cursor.getString(COLUMN_WORD);
                int frequency = cursor.getInt(COLUMN_FREQUENCY);
                String locale = cursor.getString(COLUMN_LOCALE);
                int appId = cursor.getInt(COLUMN_APPID);
                String out = name + "|" + frequency + "|" + locale + "|" + appId;
                byte[] line = out.getBytes();
                writeInt(sizeBytes, 0, line.length);
                gzip.write(sizeBytes);
                gzip.write(line);
                cursor.moveToNext();
            }
            gzip.finish();
        } catch (IOException ioe) {
            Log.e(TAG, "Couldn't compress the dictionary:\n" + ioe);
            return EMPTY_DATA;
        } finally {
            cursor.close();
        }
        return baos.toByteArray();
    }

    private void restoreDictionary(BackupDataInput data, Uri contentUri) {
        ContentValues cv = new ContentValues(2);
        byte[] dictCompressed = new byte[data.getDataSize()];
        byte[] dictionary = null;
        try {
            data.readEntityData(dictCompressed, 0, dictCompressed.length);
            GZIPInputStream gzip = new GZIPInputStream(new ByteArrayInputStream(dictCompressed));
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte[] tempData = new byte[1024];
            int got;
            while ((got = gzip.read(tempData)) > 0) {
                baos.write(tempData, 0, got);
            }
            gzip.close();
            dictionary = baos.toByteArray();
        } catch (IOException ioe) {
            Log.e(TAG, "Couldn't read and uncompress entity data:\n" + ioe);
            return;
        }
        int pos = 0;
        while (pos + 4 < dictionary.length) {
            int length = readInt(dictionary, pos);
            pos += 4;
            if (pos + length > dictionary.length) {
                Log.e(TAG, "Insufficient data");
            }
            String line = new String(dictionary, pos, length);
            pos += length;
            StringTokenizer st = new StringTokenizer(line, SEPARATOR);
            String word;
            String frequency;
            try {
                word = st.nextToken();
                frequency = st.nextToken();
                String locale = null;
                String appid = null;
                if (st.hasMoreTokens()) locale = st.nextToken();
                if ("null".equalsIgnoreCase(locale)) locale = null;
                if (st.hasMoreTokens()) appid = st.nextToken();
                int frequencyInt = Integer.parseInt(frequency);
                int appidInt = appid != null? Integer.parseInt(appid) : 0;

                if (!TextUtils.isEmpty(frequency)) {
                    cv.clear();
                    cv.put(Words.WORD, word);
                    cv.put(Words.FREQUENCY, frequencyInt);
                    cv.put(Words.LOCALE, locale);
                    cv.put(Words.APP_ID, appidInt);
                    // Remove duplicate first
                    getContentResolver().delete(contentUri, Words.WORD + "=?", new String[] {word});
                    getContentResolver().insert(contentUri, cv);
                }
            } catch (NoSuchElementException nsee) {
                Log.e(TAG, "Token format error\n" + nsee);
            } catch (NumberFormatException nfe) {
                Log.e(TAG, "Number format error\n" + nfe);
            }
        }
    }

    /**
     * Write an int in BigEndian into the byte array.
     * @param out byte array
     * @param pos current pos in array
     * @param value integer to write
     * @return the index after adding the size of an int (4)
     */
    private int writeInt(byte[] out, int pos, int value) {
        out[pos + 0] = (byte) ((value >> 24) & 0xFF);
        out[pos + 1] = (byte) ((value >> 16) & 0xFF);
        out[pos + 2] = (byte) ((value >>  8) & 0xFF);
        out[pos + 3] = (byte) ((value >>  0) & 0xFF);
        return pos + 4;
    }

    private int readInt(byte[] in, int pos) {
        int result =
                ((in[pos    ] & 0xFF) << 24) |
                ((in[pos + 1] & 0xFF) << 16) |
                ((in[pos + 2] & 0xFF) <<  8) |
                ((in[pos + 3] & 0xFF) <<  0);
        return result;
    }
}
