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

import android.content.ContentProvider;
import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
import android.content.ContentValues;
import android.content.Context;
import android.content.OperationApplicationException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteTransactionListener;
import android.net.Uri;
import android.os.Binder;
import android.os.Process;
import android.provider.CalendarContract;

import java.util.ArrayList;

/**
 * General purpose {@link ContentProvider} base class that uses SQLiteDatabase for storage.
 */
public abstract class SQLiteContentProvider extends ContentProvider
        implements SQLiteTransactionListener {

    private static final String TAG = "SQLiteContentProvider";

    private SQLiteOpenHelper mOpenHelper;
    private volatile boolean mNotifyChange;
    protected SQLiteDatabase mDb;

    private final ThreadLocal<Boolean> mApplyingBatch = new ThreadLocal<Boolean>();
    private static final int SLEEP_AFTER_YIELD_DELAY = 4000;

    private Boolean mIsCallerSyncAdapter;

    @Override
    public boolean onCreate() {
        Context context = getContext();
        mOpenHelper = getDatabaseHelper(context);
        return true;
    }

    protected abstract SQLiteOpenHelper getDatabaseHelper(Context context);

    /**
     * The equivalent of the {@link #insert} method, but invoked within a transaction.
     */
    protected abstract Uri insertInTransaction(Uri uri, ContentValues values,
            boolean callerIsSyncAdapter);

    /**
     * The equivalent of the {@link #update} method, but invoked within a transaction.
     */
    protected abstract int updateInTransaction(Uri uri, ContentValues values, String selection,
            String[] selectionArgs, boolean callerIsSyncAdapter);

    /**
     * The equivalent of the {@link #delete} method, but invoked within a transaction.
     */
    protected abstract int deleteInTransaction(Uri uri, String selection, String[] selectionArgs,
            boolean callerIsSyncAdapter);

    protected abstract void notifyChange(boolean syncToNetwork);

    protected SQLiteOpenHelper getDatabaseHelper() {
        return mOpenHelper;
    }

    private boolean applyingBatch() {
        return mApplyingBatch.get() != null && mApplyingBatch.get();
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        Uri result = null;
        boolean applyingBatch = applyingBatch();
        boolean isCallerSyncAdapter = getIsCallerSyncAdapter(uri);
        if (!applyingBatch) {
            mDb = mOpenHelper.getWritableDatabase();
            mDb.beginTransactionWithListener(this);
            final long identity = clearCallingIdentityInternal();
            try {
                result = insertInTransaction(uri, values, isCallerSyncAdapter);
                if (result != null) {
                    mNotifyChange = true;
                }
                mDb.setTransactionSuccessful();
            } finally {
                restoreCallingIdentityInternal(identity);
                mDb.endTransaction();
            }

            onEndTransaction(!isCallerSyncAdapter && shouldSyncFor(uri));
        } else {
            result = insertInTransaction(uri, values, isCallerSyncAdapter);
            if (result != null) {
                mNotifyChange = true;
            }
        }
        return result;
    }

    @Override
    public int bulkInsert(Uri uri, ContentValues[] values) {
        int numValues = values.length;
        boolean isCallerSyncAdapter = getIsCallerSyncAdapter(uri);
        mDb = mOpenHelper.getWritableDatabase();
        mDb.beginTransactionWithListener(this);
        final long identity = clearCallingIdentityInternal();
        try {
            for (int i = 0; i < numValues; i++) {
                Uri result = insertInTransaction(uri, values[i], isCallerSyncAdapter);
                if (result != null) {
                    mNotifyChange = true;
                }
                mDb.yieldIfContendedSafely();
            }
            mDb.setTransactionSuccessful();
        } finally {
            restoreCallingIdentityInternal(identity);
            mDb.endTransaction();
        }

        onEndTransaction(!isCallerSyncAdapter);
        return numValues;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        int count = 0;
        boolean applyingBatch = applyingBatch();
        boolean isCallerSyncAdapter = getIsCallerSyncAdapter(uri);
        if (!applyingBatch) {
            mDb = mOpenHelper.getWritableDatabase();
            mDb.beginTransactionWithListener(this);
            final long identity = clearCallingIdentityInternal();
            try {
                count = updateInTransaction(uri, values, selection, selectionArgs,
                            isCallerSyncAdapter);
                if (count > 0) {
                    mNotifyChange = true;
                }
                mDb.setTransactionSuccessful();
            } finally {
                restoreCallingIdentityInternal(identity);
                mDb.endTransaction();
            }

            onEndTransaction(!isCallerSyncAdapter && shouldSyncFor(uri));
        } else {
            count = updateInTransaction(uri, values, selection, selectionArgs,
                        isCallerSyncAdapter);
            if (count > 0) {
                mNotifyChange = true;
            }
        }

        return count;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        int count = 0;
        boolean applyingBatch = applyingBatch();
        boolean isCallerSyncAdapter = getIsCallerSyncAdapter(uri);
        if (!applyingBatch) {
            mDb = mOpenHelper.getWritableDatabase();
            mDb.beginTransactionWithListener(this);
            final long identity = clearCallingIdentityInternal();
            try {
                count = deleteInTransaction(uri, selection, selectionArgs, isCallerSyncAdapter);
                if (count > 0) {
                    mNotifyChange = true;
                }
                mDb.setTransactionSuccessful();
            } finally {
                restoreCallingIdentityInternal(identity);
                mDb.endTransaction();
            }

            onEndTransaction(!isCallerSyncAdapter && shouldSyncFor(uri));
        } else {
            count = deleteInTransaction(uri, selection, selectionArgs, isCallerSyncAdapter);
            if (count > 0) {
                mNotifyChange = true;
            }
        }
        return count;
    }

    protected boolean getIsCallerSyncAdapter(Uri uri) {
        boolean isCurrentSyncAdapter = QueryParameterUtils.readBooleanQueryParameter(uri,
                CalendarContract.CALLER_IS_SYNCADAPTER, false);
        if (mIsCallerSyncAdapter == null || mIsCallerSyncAdapter) {
            mIsCallerSyncAdapter = isCurrentSyncAdapter;
        }
        return isCurrentSyncAdapter;
    }

    @Override
    public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
            throws OperationApplicationException {
        final int numOperations = operations.size();
        if (numOperations == 0) {
            return new ContentProviderResult[0];
        }
        mDb = mOpenHelper.getWritableDatabase();
        mDb.beginTransactionWithListener(this);
        final boolean isCallerSyncAdapter = getIsCallerSyncAdapter(operations.get(0).getUri());
        final long identity = clearCallingIdentityInternal();
        try {
            mApplyingBatch.set(true);
            final ContentProviderResult[] results = new ContentProviderResult[numOperations];
            for (int i = 0; i < numOperations; i++) {
                final ContentProviderOperation operation = operations.get(i);
                if (i > 0 && operation.isYieldAllowed()) {
                    mDb.yieldIfContendedSafely(SLEEP_AFTER_YIELD_DELAY);
                }
                results[i] = operation.apply(this, results, i);
            }
            mDb.setTransactionSuccessful();
            return results;
        } finally {
            mApplyingBatch.set(false);
            mDb.endTransaction();
            onEndTransaction(!isCallerSyncAdapter);
            restoreCallingIdentityInternal(identity);
        }
    }

    public void onBegin() {
        mIsCallerSyncAdapter = null;
        onBeginTransaction();
    }

    public void onCommit() {
        beforeTransactionCommit();
    }

    public void onRollback() {
        // not used
    }

    protected void onBeginTransaction() {
    }

    protected void beforeTransactionCommit() {
    }

    protected void onEndTransaction(boolean syncToNetwork) {
        if (mNotifyChange) {
            mNotifyChange = false;
            // We sync to network if the caller was not the sync adapter
            notifyChange(syncToNetwork);
        }
    }

    /**
     * Some URI's are maintained locally so we should not request a sync for them
     */
    protected abstract boolean shouldSyncFor(Uri uri);

    /** The package to most recently query(), not including further internally recursive calls. */
    private final ThreadLocal<String> mCallingPackage = new ThreadLocal<String>();

    /**
     * The calling Uid when a calling package is cached, so we know when the stack of any
     * recursive calls to clearCallingIdentity and restoreCallingIdentity is complete.
     */
    private final ThreadLocal<Integer> mOriginalCallingUid = new ThreadLocal<Integer>();


    protected String getCachedCallingPackage() {
        return mCallingPackage.get();
    }

    /**
     * Call {@link android.os.Binder#clearCallingIdentity()}, while caching the calling package
     * name, so that it can be saved if this is part of an event mutation.
     */
    protected long clearCallingIdentityInternal() {
        // Only set the calling package if the calling UID is not our own.
        int uid = Process.myUid();
        int callingUid = Binder.getCallingUid();
        if (uid != callingUid) {
            try {
                mOriginalCallingUid.set(callingUid);
                String callingPackage = getCallingPackage();
                mCallingPackage.set(callingPackage);
            } catch (SecurityException e) {
                // If this exception is thrown, clearCallingIdentity has already been called, and
                // calling package is already available.
            }
        }

        return Binder.clearCallingIdentity();
    }

    /**
     * Call {@link Binder#restoreCallingIdentity(long)}.
     * </p>
     * If this is the last restore on the stack of calls to
     * {@link android.os.Binder#clearCallingIdentity()}, then the cached calling package will also
     * be cleared.
     * @param identity
     */
    protected void restoreCallingIdentityInternal(long identity) {
        Binder.restoreCallingIdentity(identity);

        int callingUid = Binder.getCallingUid();
        if (mOriginalCallingUid.get() != null && mOriginalCallingUid.get() == callingUid) {
            mCallingPackage.set(null);
            mOriginalCallingUid.set(null);
        }
    }
}
