package android.test;

import com.google.android.collect.Sets;

import android.content.Context;
import android.content.ContextWrapper;
import android.content.ContentProvider;
import android.database.sqlite.SQLiteDatabase;
import android.os.FileUtils;
import android.util.Log;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.Set;

/**
 * This is a class which delegates to the given context, but performs database
 * and file operations with a renamed database/file name (prefixes default
 * names with a given prefix).
 */
public class RenamingDelegatingContext extends ContextWrapper {

    private Context mFileContext;
    private String mFilePrefix = null;
    private File mCacheDir;
    private final Object mSync = new Object();

    private Set<String> mDatabaseNames = Sets.newHashSet();
    private Set<String> mFileNames = Sets.newHashSet();

    public static <T extends ContentProvider> T providerWithRenamedContext(
            Class<T> contentProvider, Context c, String filePrefix)
            throws IllegalAccessException, InstantiationException {
        return providerWithRenamedContext(contentProvider, c, filePrefix, false);
    }

    public static <T extends ContentProvider> T providerWithRenamedContext(
            Class<T> contentProvider, Context c, String filePrefix,
            boolean allowAccessToExistingFilesAndDbs)
            throws IllegalAccessException, InstantiationException {
        Class<T> mProviderClass = contentProvider;
        T mProvider = mProviderClass.newInstance();
        RenamingDelegatingContext mContext = new RenamingDelegatingContext(c, filePrefix);
        if (allowAccessToExistingFilesAndDbs) {
            mContext.makeExistingFilesAndDbsAccessible();
        }
        mProvider.attachInfo(mContext, null);
        return mProvider;
    }

    /**
     * Makes accessible all files and databases whose names match the filePrefix that was passed to
     * the constructor. Normally only files and databases that were created through this context are
     * accessible.
     */
    public void makeExistingFilesAndDbsAccessible() {
        String[] databaseList = mFileContext.databaseList();
        for (String diskName : databaseList) {
            if (shouldDiskNameBeVisible(diskName)) {
                mDatabaseNames.add(publicNameFromDiskName(diskName));
            }
        }
        String[] fileList = mFileContext.fileList();
        for (String diskName : fileList) {
            if (shouldDiskNameBeVisible(diskName)) {
                mFileNames.add(publicNameFromDiskName(diskName));
            }
        }
    }

    /**
     * Returns if the given diskName starts with the given prefix or not.
     * @param diskName name of the database/file.
     */
    boolean shouldDiskNameBeVisible(String diskName) {
        return diskName.startsWith(mFilePrefix);
    }

    /**
     * Returns the public name (everything following the prefix) of the given diskName.
     * @param diskName name of the database/file.
     */
    String publicNameFromDiskName(String diskName) {
        if (!shouldDiskNameBeVisible(diskName)) {
            throw new IllegalArgumentException("disk file should not be visible: " + diskName);
        }
        return diskName.substring(mFilePrefix.length(), diskName.length());
    }

    /**
     * @param context : the context that will be delagated.
     * @param filePrefix : a prefix with which database and file names will be
     * prefixed.
     */
    public RenamingDelegatingContext(Context context, String filePrefix) {
        super(context);
        mFileContext = context;
        mFilePrefix = filePrefix;
    }

    /**
     * @param context : the context that will be delagated.
     * @param fileContext : the context that file and db methods will be delgated to
     * @param filePrefix : a prefix with which database and file names will be
     * prefixed.
     */
    public RenamingDelegatingContext(Context context, Context fileContext, String filePrefix) {
        super(context);
        mFileContext = fileContext;
        mFilePrefix = filePrefix;
    }

    public String getDatabasePrefix() {
        return mFilePrefix;
    }

    private String renamedFileName(String name) {
        return mFilePrefix + name;
    }

    @Override
    public SQLiteDatabase openOrCreateDatabase(String name,
            int mode, SQLiteDatabase.CursorFactory factory) {
        final String internalName = renamedFileName(name);
        if (!mDatabaseNames.contains(name)) {
            mDatabaseNames.add(name);
            mFileContext.deleteDatabase(internalName);
        }
        return mFileContext.openOrCreateDatabase(internalName, mode, factory);
    }

    @Override
    public boolean deleteDatabase(String name) {
        if (mDatabaseNames.contains(name)) {
            mDatabaseNames.remove(name);
            return mFileContext.deleteDatabase(renamedFileName(name));
        } else {
            return false;
        }
    }
    
    @Override
    public File getDatabasePath(String name) {
        return mFileContext.getDatabasePath(renamedFileName(name));
    }

    @Override
    public String[] databaseList() {
        return mDatabaseNames.toArray(new String[]{});
    }

    @Override
    public FileInputStream openFileInput(String name)
            throws FileNotFoundException {
        final String internalName = renamedFileName(name);
        if (mFileNames.contains(name)) {
            return mFileContext.openFileInput(internalName);
        } else {
            throw new FileNotFoundException(internalName);
        }
    }

    @Override
    public FileOutputStream openFileOutput(String name, int mode)
            throws FileNotFoundException {
        mFileNames.add(name);
        return mFileContext.openFileOutput(renamedFileName(name), mode);
    }

    @Override
    public File getFileStreamPath(String name) {
        return mFileContext.getFileStreamPath(renamedFileName(name));
    }

    @Override
    public boolean deleteFile(String name) {
        if (mFileNames.contains(name)) {
            mFileNames.remove(name);
            return mFileContext.deleteFile(renamedFileName(name));
        } else {
            return false;
        }
    }

    @Override
    public String[] fileList() {
        return mFileNames.toArray(new String[]{});
    }
    
    /**
     * In order to support calls to getCacheDir(), we create a temp cache dir (inside the real
     * one) and return it instead.  This code is basically getCacheDir(), except it uses the real
     * cache dir as the parent directory and creates a test cache dir inside that.
     */
    @Override
    public File getCacheDir() {
        synchronized (mSync) {
            if (mCacheDir == null) {
                mCacheDir = new File(mFileContext.getCacheDir(), renamedFileName("cache"));
            }
            if (!mCacheDir.exists()) {
                if(!mCacheDir.mkdirs()) {
                    Log.w("RenamingDelegatingContext", "Unable to create cache directory");
                    return null;
                }
                FileUtils.setPermissions(
                        mCacheDir.getPath(),
                        FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
                        -1, -1);
            }
        }
        return mCacheDir;
    }


//    /**
//     * Given an array of files returns only those whose names indicate that they belong to this
//     * context.
//     * @param allFiles the original list of files
//     * @return the pruned list of files
//     */
//    private String[] prunedFileList(String[] allFiles) {
//        List<String> files = Lists.newArrayList();
//        for (String file : allFiles) {
//            if (file.startsWith(mFilePrefix)) {
//                files.add(file);
//            }
//        }
//        return files.toArray(new String[]{});
//    }
}