/*
 * Copyright (C) 2006 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 android.database;

import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;


/**
 * Wraps a BulkCursor around an existing Cursor making it remotable.
 *
 * {@hide}
 */
public final class CursorToBulkCursorAdaptor extends BulkCursorNative 
        implements IBinder.DeathRecipient {
    private static final String TAG = "Cursor";
    private final CrossProcessCursor mCursor;
    private CursorWindow mWindow;
    private final String mProviderName;
    private ContentObserverProxy mObserver;

    private static final class ContentObserverProxy extends ContentObserver 
            {
        protected IContentObserver mRemote;

        public ContentObserverProxy(IContentObserver remoteObserver, DeathRecipient recipient) {
            super(null);
            mRemote = remoteObserver;
            try {
                remoteObserver.asBinder().linkToDeath(recipient, 0);
            } catch (RemoteException e) {
                // Do nothing, the far side is dead
            }
        }
        
        public boolean unlinkToDeath(DeathRecipient recipient) {
            return mRemote.asBinder().unlinkToDeath(recipient, 0);
        }

        @Override
        public boolean deliverSelfNotifications() {
            // The far side handles the self notifications.
            return false;
        }

        @Override
        public void onChange(boolean selfChange) {
            try {
                mRemote.onChange(selfChange);
            } catch (RemoteException ex) {
                // Do nothing, the far side is dead
            }
        }
    }

    public CursorToBulkCursorAdaptor(Cursor cursor, IContentObserver observer, String providerName,
            boolean allowWrite, CursorWindow window) {
        try {
            mCursor = (CrossProcessCursor) cursor;
            if (mCursor instanceof AbstractWindowedCursor) {
                AbstractWindowedCursor windowedCursor = (AbstractWindowedCursor) cursor;
                if (windowedCursor.hasWindow()) {
                    if (Log.isLoggable(TAG, Log.VERBOSE) || false) {
                        Log.v(TAG, "Cross process cursor has a local window before setWindow in "
                                + providerName, new RuntimeException());
                    }
                }
                windowedCursor.setWindow(window);
            } else {
                mWindow = window;
                mCursor.fillWindow(0, window);
            }
        } catch (ClassCastException e) {
            // TODO Implement this case.
            throw new UnsupportedOperationException(
                    "Only CrossProcessCursor cursors are supported across process for now", e);
        }
        mProviderName = providerName;

        createAndRegisterObserverProxy(observer);
    }
    
    public void binderDied() {
        mCursor.close();
        if (mWindow != null) {
            mWindow.close();
        }
    }
    
    public CursorWindow getWindow(int startPos) {
        mCursor.moveToPosition(startPos);
        
        if (mWindow != null) {
            if (startPos < mWindow.getStartPosition() ||
                    startPos >= (mWindow.getStartPosition() + mWindow.getNumRows())) {
                mCursor.fillWindow(startPos, mWindow);
            }            
            return mWindow;
        } else {
            return ((AbstractWindowedCursor)mCursor).getWindow();
        }
    }

    public void onMove(int position) {
        mCursor.onMove(mCursor.getPosition(), position);
    }

    public int count() {
        return mCursor.getCount();
    }

    public String[] getColumnNames() {
        return mCursor.getColumnNames();
    }

    public void deactivate() {
        maybeUnregisterObserverProxy();
        mCursor.deactivate();
    }

    public void close() {
        maybeUnregisterObserverProxy();
        mCursor.close();
    }

    public int requery(IContentObserver observer, CursorWindow window) {
        if (mWindow == null) {
            ((AbstractWindowedCursor)mCursor).setWindow(window);
        }
        try {
            if (!mCursor.requery()) {
                return -1;
            }
        } catch (IllegalStateException e) {
            IllegalStateException leakProgram = new IllegalStateException(
                    mProviderName + " Requery misuse db, mCursor isClosed:" +
                    mCursor.isClosed(), e);
            throw leakProgram;
        }
        
        if (mWindow != null) {
            mCursor.fillWindow(0, window);
            mWindow = window;
        }
        maybeUnregisterObserverProxy();
        createAndRegisterObserverProxy(observer);
        return mCursor.getCount();
    }

    public boolean getWantsAllOnMoveCalls() {
        return mCursor.getWantsAllOnMoveCalls();
    }

    /**
     * Create a ContentObserver from the observer and register it as an observer on the
     * underlying cursor.
     * @param observer the IContentObserver that wants to monitor the cursor
     * @throws IllegalStateException if an observer is already registered
     */
    private void createAndRegisterObserverProxy(IContentObserver observer) {
        if (mObserver != null) {
            throw new IllegalStateException("an observer is already registered");
        }
        mObserver = new ContentObserverProxy(observer, this);
        mCursor.registerContentObserver(mObserver);
    }

    /** Unregister the observer if it is already registered. */
    private void maybeUnregisterObserverProxy() {
        if (mObserver != null) {
            mCursor.unregisterContentObserver(mObserver);
            mObserver.unlinkToDeath(this);
            mObserver = null;
        }
    }

    public Bundle getExtras() {
        return mCursor.getExtras();
    }

    public Bundle respond(Bundle extras) {
        return mCursor.respond(extras);
    }
}
