/*
 * Copyright (C) 2011 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.contacts;

import android.content.ContentValues;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.provider.ContactsContract.PhotoFiles;
import android.util.Log;

import com.android.providers.contacts.ContactsDatabaseHelper.PhotoFilesColumns;
import com.android.providers.contacts.ContactsDatabaseHelper.Tables;
import com.google.common.annotations.VisibleForTesting;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * Photo storage system that stores the files directly onto the hard disk
 * in the specified directory.
 */
public class PhotoStore {

    private static final Object MKDIRS_LOCK = new Object();

    private final String TAG = PhotoStore.class.getSimpleName();

    // Directory name under the root directory for photo storage.
    private final String DIRECTORY = "photos";

    /** Map of keys to entries in the directory. */
    private final Map<Long, Entry> mEntries;

    /** Total amount of space currently used by the photo store in bytes. */
    private long mTotalSize = 0;

    /** The file path for photo storage. */
    private final File mStorePath;

    /** The database helper. */
    private final ContactsDatabaseHelper mDatabaseHelper;

    /** The database to use for storing metadata for the photo files. */
    private SQLiteDatabase mDb;

    /**
     * Constructs an instance of the PhotoStore under the specified directory.
     * @param rootDirectory The root directory of the storage.
     * @param databaseHelper Helper class for obtaining a database instance.
     */
    public PhotoStore(File rootDirectory, ContactsDatabaseHelper databaseHelper) {
        mStorePath = new File(rootDirectory, DIRECTORY);
        synchronized (MKDIRS_LOCK) {
            if (!mStorePath.exists()) {
                if (!mStorePath.mkdirs()) {
                    throw new RuntimeException("Unable to create photo storage directory "
                            + mStorePath.getPath());
                }
            }
        }
        mDatabaseHelper = databaseHelper;
        mEntries = new HashMap<Long, Entry>();
        initialize();
    }

    /**
     * Clears the photo storage. Deletes all files from disk.
     */
    public void clear() {
        File[] files = mStorePath.listFiles();
        if (files != null) {
            for (File file : files) {
                cleanupFile(file);
            }
        }
        if (mDb == null) {
            mDb = mDatabaseHelper.getWritableDatabase();
        }
        mDb.delete(Tables.PHOTO_FILES, null, null);
        mEntries.clear();
        mTotalSize = 0;
    }

    @VisibleForTesting
    public long getTotalSize() {
        return mTotalSize;
    }

    /**
     * Returns the entry with the specified key if it exists, null otherwise.
     */
    public Entry get(long key) {
        return mEntries.get(key);
    }

    /**
     * Initializes the PhotoStore by scanning for all files currently in the
     * specified root directory.
     */
    public final void initialize() {
        File[] files = mStorePath.listFiles();
        if (files == null) {
            return;
        }
        for (File file : files) {
            try {
                Entry entry = new Entry(file);
                putEntry(entry.id, entry);
            } catch (NumberFormatException nfe) {
                // Not a valid photo store entry - delete the file.
                cleanupFile(file);
            }
        }

        // Get a reference to the database.
        mDb = mDatabaseHelper.getWritableDatabase();
    }

    /**
     * Cleans up the photo store such that only the keys in use still remain as
     * entries in the store (all other entries are deleted).
     *
     * If an entry in the keys in use does not exist in the photo store, that key
     * will be returned in the result set - the caller should take steps to clean
     * up those references, as the underlying photo entries do not exist.
     *
     * @param keysInUse The set of all keys that are in use in the photo store.
     * @return The set of the keys in use that refer to non-existent entries.
     */
    public Set<Long> cleanup(Set<Long> keysInUse) {
        Set<Long> keysToRemove = new HashSet<Long>();
        keysToRemove.addAll(mEntries.keySet());
        keysToRemove.removeAll(keysInUse);
        if (!keysToRemove.isEmpty()) {
            Log.d(TAG, "cleanup removing " + keysToRemove.size() + " entries");
            for (long key : keysToRemove) {
                remove(key);
            }
        }

        Set<Long> missingKeys = new HashSet<Long>();
        missingKeys.addAll(keysInUse);
        missingKeys.removeAll(mEntries.keySet());
        return missingKeys;
    }

    /**
     * Inserts the photo in the given photo processor into the photo store.  If the display photo
     * is already thumbnail-sized or smaller, this will do nothing (and will return 0).
     * @param photoProcessor A photo processor containing the photo data to insert.
     * @return The photo file ID associated with the file, or 0 if the file could not be created or
     *     is thumbnail-sized or smaller.
     */
    public long insert(PhotoProcessor photoProcessor) {
        return insert(photoProcessor, false);
    }

    /**
     * Inserts the photo in the given photo processor into the photo store.  If the display photo
     * is already thumbnail-sized or smaller, this will do nothing (and will return 0) unless
     * allowSmallImageStorage is specified.
     * @param photoProcessor A photo processor containing the photo data to insert.
     * @param allowSmallImageStorage Whether thumbnail-sized or smaller photos should still be
     *     stored in the file store.
     * @return The photo file ID associated with the file, or 0 if the file could not be created or
     *     is thumbnail-sized or smaller and allowSmallImageStorage is false.
     */
    public long insert(PhotoProcessor photoProcessor, boolean allowSmallImageStorage) {
        Bitmap displayPhoto = photoProcessor.getDisplayPhoto();
        int width = displayPhoto.getWidth();
        int height = displayPhoto.getHeight();
        int thumbnailDim = photoProcessor.getMaxThumbnailPhotoDim();
        if (allowSmallImageStorage || width > thumbnailDim || height > thumbnailDim) {
            // Write the photo to a temp file, create the DB record for tracking it, and rename the
            // temp file to match.
            File file = null;
            try {
                // Write the display photo to a temp file.
                byte[] photoBytes = photoProcessor.getDisplayPhotoBytes();
                file = File.createTempFile("img", null, mStorePath);
                FileOutputStream fos = new FileOutputStream(file);
                fos.write(photoBytes);
                fos.close();

                // Create the DB entry.
                ContentValues values = new ContentValues();
                values.put(PhotoFiles.HEIGHT, height);
                values.put(PhotoFiles.WIDTH, width);
                values.put(PhotoFiles.FILESIZE, photoBytes.length);
                long id = mDb.insert(Tables.PHOTO_FILES, null, values);
                if (id != 0) {
                    // Rename the temp file.
                    File target = getFileForPhotoFileId(id);
                    if (file.renameTo(target)) {
                        Entry entry = new Entry(target);
                        putEntry(entry.id, entry);
                        return id;
                    }
                }
            } catch (IOException e) {
                // Write failed - will delete the file below.
            }

            // If anything went wrong, clean up the file before returning.
            if (file != null) {
                cleanupFile(file);
            }
        }
        return 0;
    }

    private void cleanupFile(File file) {
        boolean deleted = file.delete();
        if (!deleted) {
            Log.d("Could not clean up file %s", file.getAbsolutePath());
        }
    }

    /**
     * Removes the specified photo file from the store if it exists.
     */
    public void remove(long id) {
        cleanupFile(getFileForPhotoFileId(id));
        removeEntry(id);
    }

    /**
     * Returns a file object for the given photo file ID.
     */
    private File getFileForPhotoFileId(long id) {
        return new File(mStorePath, String.valueOf(id));
    }

    /**
     * Puts the entry with the specified photo file ID into the store.
     * @param id The photo file ID to identify the entry by.
     * @param entry The entry to store.
     */
    private void putEntry(long id, Entry entry) {
        if (!mEntries.containsKey(id)) {
            mTotalSize += entry.size;
        } else {
            Entry oldEntry = mEntries.get(id);
            mTotalSize += (entry.size - oldEntry.size);
        }
        mEntries.put(id, entry);
    }

    /**
     * Removes the entry identified by the given photo file ID from the store, removing
     * the associated photo file entry from the database.
     */
    private void removeEntry(long id) {
        Entry entry = mEntries.get(id);
        if (entry != null) {
            mTotalSize -= entry.size;
            mEntries.remove(id);
        }
        mDb.delete(ContactsDatabaseHelper.Tables.PHOTO_FILES, PhotoFilesColumns.CONCRETE_ID + "=?",
                new String[]{String.valueOf(id)});
    }

    public static class Entry {
        /** The photo file ID that identifies the entry. */
        public final long id;

        /** The size of the data, in bytes. */
        public final long size;

        /** The path to the file. */
        public final String path;

        public Entry(File file) {
            id = Long.parseLong(file.getName());
            size = file.length();
            path = file.getAbsolutePath();
        }
    }
}
