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

import android.app.Activity;
import android.app.Application;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.os.IBinder;
import android.test.mock.MockApplication;
import android.view.Window;

/**
 * This class provides isolated testing of a single activity.  The activity under test will
 * be created with minimal connection to the system infrastructure, and you can inject mocked or 
 * wrappered versions of many of Activity's dependencies.  Most of the work is handled
 * automatically here by {@link #setUp} and {@link #tearDown}.
 * 
 * <p>If you prefer a functional test, see {@link android.test.ActivityInstrumentationTestCase}.
 * 
 * <p>It must be noted that, as a true unit test, your Activity will not be running in the
 * normal system and will not participate in the normal interactions with other Activities.  
 * The following methods should not be called in this configuration - most of them will throw
 * exceptions:
 * <ul>
 * <li>{@link android.app.Activity#createPendingResult(int, Intent, int)}</li>
 * <li>{@link android.app.Activity#startActivityIfNeeded(Intent, int)}</li>
 * <li>{@link android.app.Activity#startActivityFromChild(Activity, Intent, int)}</li>
 * <li>{@link android.app.Activity#startNextMatchingActivity(Intent)}</li>
 * <li>{@link android.app.Activity#getCallingActivity()}</li>
 * <li>{@link android.app.Activity#getCallingPackage()}</li>
 * <li>{@link android.app.Activity#createPendingResult(int, Intent, int)}</li>
 * <li>{@link android.app.Activity#getTaskId()}</li>
 * <li>{@link android.app.Activity#isTaskRoot()}</li>
 * <li>{@link android.app.Activity#moveTaskToBack(boolean)}</li>
 * <li>{@link android.app.Activity#setPersistent(boolean)}</li>
 * </ul>
 * 
 * <p>The following methods may be called but will not do anything.  For test purposes, you can use 
 * the methods {@link #getStartedActivityIntent()} and {@link #getStartedActivityRequest()} to 
 * inspect the parameters that they were called with.
 * <ul>
 * <li>{@link android.app.Activity#startActivity(Intent)}</li>
 * <li>{@link android.app.Activity#startActivityForResult(Intent, int)}</li>
 * </ul>
 *
 * <p>The following methods may be called but will not do anything.  For test purposes, you can use 
 * the methods {@link #isFinishCalled()} and {@link #getFinishedActivityRequest()} to inspect the 
 * parameters that they were called with.
 * <ul>
 * <li>{@link android.app.Activity#finish()}</li>
 * <li>{@link android.app.Activity#finishFromChild(Activity child)}</li>
 * <li>{@link android.app.Activity#finishActivity(int requestCode)}</li>
 * </ul>
 *
 */
public abstract class ActivityUnitTestCase<T extends Activity> 
        extends ActivityTestCase {

    private Class<T> mActivityClass;

    private Context mActivityContext;
    private Application mApplication;
    private MockParent mMockParent;

    private boolean mAttached = false;
    private boolean mCreated = false;

    public ActivityUnitTestCase(Class<T> activityClass) {
        mActivityClass = activityClass;
    }

    @Override
    public T getActivity() {
        return (T) super.getActivity();
    }

    @Override
    protected void setUp() throws Exception {
        super.setUp();

        // default value for target context, as a default
      mActivityContext = getInstrumentation().getTargetContext();
    }
    
    /**
     * Start the activity under test, in the same way as if it was started by
     * {@link android.content.Context#startActivity Context.startActivity()}, providing the 
     * arguments it supplied.  When you use this method to start the activity, it will automatically
     * be stopped by {@link #tearDown}.
     * 
     * <p>This method will call onCreate(), but if you wish to further exercise Activity life 
     * cycle methods, you must call them yourself from your test case.
     * 
     * <p><i>Do not call from your setUp() method.  You must call this method from each of your
     * test methods.</i>
     *  
     * @param intent The Intent as if supplied to {@link android.content.Context#startActivity}.
     * @param savedInstanceState The instance state, if you are simulating this part of the life
     * cycle.  Typically null.
     * @param lastNonConfigurationInstance This Object will be available to the 
     * Activity if it calls {@link android.app.Activity#getLastNonConfigurationInstance()}.  
     * Typically null.
     * @return Returns the Activity that was created
     */
    protected T startActivity(Intent intent, Bundle savedInstanceState,
            Object lastNonConfigurationInstance) {
        assertFalse("Activity already created", mCreated);
        
        if (!mAttached) {
            assertNotNull(mActivityClass);
            setActivity(null);
            T newActivity = null;
            try {
                IBinder token = null;
                if (mApplication == null) {
                    setApplication(new MockApplication());
                }
                ComponentName cn = new ComponentName(mActivityClass.getPackage().getName(), 
                        mActivityClass.getName());
                intent.setComponent(cn);
                ActivityInfo info = new ActivityInfo();
                CharSequence title = mActivityClass.getName();
                mMockParent = new MockParent();
                String id = null;
                        
                newActivity = (T) getInstrumentation().newActivity(mActivityClass, mActivityContext,
                        token, mApplication, intent, info, title, mMockParent, id,
                        lastNonConfigurationInstance);
            } catch (Exception e) {
                assertNotNull(newActivity);
            }
            
            assertNotNull(newActivity);
            setActivity(newActivity);
            
            mAttached = true;
        }
        
        T result = getActivity();
        if (result != null) {
            getInstrumentation().callActivityOnCreate(getActivity(), savedInstanceState);
            mCreated = true;
        }
        return result;
    }
    
    @Override
    protected void tearDown() throws Exception {
        
        setActivity(null);
        
        // Scrub out members - protects against memory leaks in the case where someone 
        // creates a non-static inner class (thus referencing the test case) and gives it to
        // someone else to hold onto
        scrubClass(ActivityInstrumentationTestCase.class);

        super.tearDown();
    }
    
    /**
     * Set the application for use during the test.  You must call this function before calling 
     * {@link #startActivity}.  If your test does not call this method,
     * @param application The Application object that will be injected into the Activity under test.
     */
    public void setApplication(Application application) {
        mApplication = application;
    }

    /**
     * If you wish to inject a Mock, Isolated, or otherwise altered context, you can do so
     * here.  You must call this function before calling {@link #startActivity}.  If you wish to
     * obtain a real Context, as a building block, use getInstrumentation().getTargetContext().
     */
    public void setActivityContext(Context activityContext) {
        mActivityContext = activityContext;
    }

    /**
     * This method will return the value if your Activity under test calls 
     * {@link android.app.Activity#setRequestedOrientation}.
     */
    public int getRequestedOrientation() {
        if (mMockParent != null) {
            return mMockParent.mRequestedOrientation;
        }
        return 0;
    }
    
    /**
     * This method will return the launch intent if your Activity under test calls 
     * {@link android.app.Activity#startActivity(Intent)} or 
     * {@link android.app.Activity#startActivityForResult(Intent, int)}.
     * @return The Intent provided in the start call, or null if no start call was made.
     */
    public Intent getStartedActivityIntent() {
        if (mMockParent != null) {
            return mMockParent.mStartedActivityIntent;
        }
        return null;
    }
    
    /**
     * This method will return the launch request code if your Activity under test calls 
     * {@link android.app.Activity#startActivityForResult(Intent, int)}.
     * @return The request code provided in the start call, or -1 if no start call was made.
     */
    public int getStartedActivityRequest() {
        if (mMockParent != null) {
            return mMockParent.mStartedActivityRequest;
        }
        return 0;
    }

    /**
     * This method will notify you if the Activity under test called 
     * {@link android.app.Activity#finish()}, 
     * {@link android.app.Activity#finishFromChild(Activity)}, or 
     * {@link android.app.Activity#finishActivity(int)}.
     * @return Returns true if one of the listed finish methods was called.
     */
    public boolean isFinishCalled() {
        if (mMockParent != null) {
            return mMockParent.mFinished;
        }
        return false;
    }
    
    /**
     * This method will return the request code if the Activity under test called 
     * {@link android.app.Activity#finishActivity(int)}.
     * @return The request code provided in the start call, or -1 if no finish call was made.
     */
    public int getFinishedActivityRequest() {
        if (mMockParent != null) {
            return mMockParent.mFinishedActivityRequest;
        }
        return 0;
    }
    
    /**
     * This mock Activity represents the "parent" activity.  By injecting this, we allow the user
     * to call a few more Activity methods, including:
     * <ul>
     * <li>{@link android.app.Activity#getRequestedOrientation()}</li>
     * <li>{@link android.app.Activity#setRequestedOrientation(int)}</li>
     * <li>{@link android.app.Activity#finish()}</li>
     * <li>{@link android.app.Activity#finishActivity(int requestCode)}</li>
     * <li>{@link android.app.Activity#finishFromChild(Activity child)}</li>
     * </ul>
     * 
     * TODO: Make this overrideable, and the unit test can look for calls to other methods
     */
    private static class MockParent extends Activity {

        public int mRequestedOrientation = 0;
        public Intent mStartedActivityIntent = null;
        public int mStartedActivityRequest = -1;
        public boolean mFinished = false;
        public int mFinishedActivityRequest = -1;

        /**
         * Implementing in the parent allows the user to call this function on the tested activity.
         */
        @Override
        public void setRequestedOrientation(int requestedOrientation) {
            mRequestedOrientation = requestedOrientation;
        }

        /**
         * Implementing in the parent allows the user to call this function on the tested activity.
         */
        @Override
        public int getRequestedOrientation() {
            return mRequestedOrientation;
        }

        /**
         * By returning null here, we inhibit the creation of any "container" for the window.
         */
        @Override
        public Window getWindow() {
            return null;
        }
        
        /**
         * By defining this in the parent, we allow the tested activity to call
         * <ul>
         * <li>{@link android.app.Activity#startActivity(Intent)}</li>
         * <li>{@link android.app.Activity#startActivityForResult(Intent, int)}</li>
         * </ul>
         */
        @Override
        public void startActivityFromChild(Activity child, Intent intent, int requestCode) {
            mStartedActivityIntent = intent;
            mStartedActivityRequest = requestCode;
        }
        
        /**
         * By defining this in the parent, we allow the tested activity to call
         * <ul>
         * <li>{@link android.app.Activity#finish()}</li>
         * <li>{@link android.app.Activity#finishFromChild(Activity child)}</li>
         * </ul>
         */
        @Override
        public void finishFromChild(Activity child) {
            mFinished = true;
        }

        /**
         * By defining this in the parent, we allow the tested activity to call
         * <ul>
         * <li>{@link android.app.Activity#finishActivity(int requestCode)}</li>
         * </ul>
         */
        @Override
        public void finishActivityFromChild(Activity child, int requestCode) {
            mFinished = true;
            mFinishedActivityRequest = requestCode;
        }
    }
}
