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

import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationManager;
import android.provider.Settings;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.MediumTest;
import android.util.Log;

/**
 * Tests for LocationManager.addProximityAlert
 * 
 * TODO: add tests for more scenarios
 * 
 * To run:
 *  adb shell am instrument -e class android.location.LocationManagerProximityTest \
 *     -w android.core/android.test.InstrumentationTestRunner
 *     
 * This test requires that the "Allow mock locations" setting be enabled     
 * 
 */
@MediumTest
public class LocationManagerProximityTest extends AndroidTestCase {

    private static final int UPDATE_LOCATION_WAIT_TIME = 1000;
    private static final int PROXIMITY_WAIT_TIME = 2000;

    private LocationManager mLocationManager;
    private PendingIntent mPendingIntent;
    private TestIntentReceiver mIntentReceiver;

    private static final String LOG_TAG = "LocationProximityTest";

    private static final String PROVIDER_NAME = "test";

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

        // test that mock locations are allowed so a more descriptive error message can be logged
        if (Settings.Secure.getInt(getContext().getContentResolver(),
            Settings.Secure.ALLOW_MOCK_LOCATION, 0) == 0) {
            fail("Mock locations are currently disabled in Settings - this test requires " +
                 "mock locations");
        }

        mLocationManager = (LocationManager) getContext().
                getSystemService(Context.LOCATION_SERVICE);
        if (mLocationManager.getProvider(PROVIDER_NAME) != null) {
            mLocationManager.removeTestProvider(PROVIDER_NAME);
        }
        
        mLocationManager.addTestProvider(PROVIDER_NAME, true, //requiresNetwork,
                false, // requiresSatellite,
                true, // requiresCell,
                false, // hasMonetaryCost,
                false, // supportsAltitude,
                false, // supportsSpeed, s
                false, // upportsBearing,
                Criteria.POWER_MEDIUM, // powerRequirement
                Criteria.ACCURACY_FINE); // accuracy
        mLocationManager.setTestProviderEnabled(PROVIDER_NAME, true);
    }

    @Override
    protected void tearDown() throws Exception {
        mLocationManager.removeTestProvider(PROVIDER_NAME);

        if (mPendingIntent != null) {
            mLocationManager.removeProximityAlert(mPendingIntent);
        }
        if (mIntentReceiver != null) {
            getContext().unregisterReceiver(mIntentReceiver);
        }
    }

    /**
     * Tests basic proximity alert when entering proximity
     */
    public void testEnterProximity() throws Exception {
        doTestEnterProximity(10000);
    }

    /**
     * Tests proximity alert when entering proximity, with no expiration 
     */
    public void testEnterProximity_noexpire() throws Exception {
        doTestEnterProximity(-1);
    }

    /**
     * Helper variant for testing enter proximity scenario 
     * TODO: add additional parameters as more scenarios are added
     * 
     * @param expiration - expiry of proximity alert 
     */
    private void doTestEnterProximity(long expiration) throws Exception {
        // update location to outside proximity range
        synchronousSendLocation(30, 30);
        registerProximityListener(0, 0, 1000, expiration);
        sendLocation(0, 0);
        waitForAlert();
        assertProximityType(true);
    }

    /**
     * Tests basic proximity alert when exiting proximity
     */
    public void testExitProximity() throws Exception {
        // first do enter proximity scenario
        doTestEnterProximity(-1);

        // now update to trigger exit proximity proximity
        mIntentReceiver.clearReceivedIntents();
        sendLocation(20, 20);
        waitForAlert();
        assertProximityType(false);
    }

    /**
     * Registers the proximity intent receiver
     */
    private void registerProximityListener(double latitude, double longitude, 
            float radius, long expiration) {
        String intentKey = "testProximity";
        Intent proximityIntent = new Intent(intentKey);
        mPendingIntent = PendingIntent.getBroadcast(getContext(), 0, 
                proximityIntent, PendingIntent.FLAG_CANCEL_CURRENT);
        mIntentReceiver = new TestIntentReceiver(intentKey);

        mLocationManager.addProximityAlert(latitude, longitude, radius, 
                expiration, mPendingIntent);

        getContext().registerReceiver(mIntentReceiver, 
                mIntentReceiver.getFilter());

    }

    /**
     * Blocks until proximity intent notification is received
     * @throws InterruptedException
     */
    private void waitForAlert() throws InterruptedException {
        Log.d(LOG_TAG, "Waiting for proximity update");
        synchronized (mIntentReceiver) {
            mIntentReceiver.wait(PROXIMITY_WAIT_TIME);
        }

        assertNotNull("Did not receive proximity alert", 
                mIntentReceiver.getLastReceivedIntent());
    }

    /**
     * Asserts that the received intent had the enter proximity property set as
     * expected
     * @param expectedEnterProximity - true if enter proximity expected, false if
     *   exit expected
     */
    private void assertProximityType(boolean expectedEnterProximity) 
            throws Exception {
        boolean proximityTest = mIntentReceiver.getLastReceivedIntent().
                getBooleanExtra(LocationManager.KEY_PROXIMITY_ENTERING, 
                !expectedEnterProximity);
        assertEquals("proximity alert not set to expected enter proximity value",
                expectedEnterProximity, proximityTest);
    }

    /**
     * Synchronous variant of sendLocation
     */
    private void synchronousSendLocation(final double latitude, 
            final double longitude)
            throws InterruptedException {
        sendLocation(latitude, longitude, this);
        // wait for location to be set
        synchronized (this) {
            wait(UPDATE_LOCATION_WAIT_TIME);
        }
    }

    /**
     * Asynchronously update the mock location provider without notification
     */
    private void sendLocation(final double latitude, final double longitude) {
        sendLocation(latitude, longitude, null);
    }

    /**
     * Asynchronously update the mock location provider with given latitude and
     * longitude
     * 
     * @param latitude - update location
     * @param longitude - update location
     * @param observer - optionally, object to notify when update is sent.If
     *            null, no update will be sent
     */
    private void sendLocation(final double latitude, final double longitude, 
            final Object observer) {
        Thread locationUpdater = new Thread() {
            @Override
            public void run() {
                Location loc = new Location(PROVIDER_NAME);
                loc.setLatitude(latitude);
                loc.setLongitude(longitude);

                loc.setTime(java.lang.System.currentTimeMillis());
                Log.d(LOG_TAG, "Sending update for " + PROVIDER_NAME);
                mLocationManager.setTestProviderLocation(PROVIDER_NAME, loc);
                if (observer != null) {
                    synchronized (observer) {
                        observer.notify();
                    }
                }
            }
        };
        locationUpdater.start();

    }

    /**
     * Helper class that receives a proximity intent and notifies the main class
     * when received
     */
    private static class TestIntentReceiver extends BroadcastReceiver {

        private String mExpectedAction;
        private Intent mLastReceivedIntent;

        public TestIntentReceiver(String expectedAction) {
            mExpectedAction = expectedAction;
            mLastReceivedIntent = null;
        }

        public IntentFilter getFilter() {
            IntentFilter filter = new IntentFilter(mExpectedAction);
            return filter;
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent != null && mExpectedAction.equals(intent.getAction())) {
                Log.d(LOG_TAG, "Intent Received: " + intent.toString());
                mLastReceivedIntent = intent;
                synchronized (this) {
                    notify();
                }
            }
        }

        public Intent getLastReceivedIntent() {
            return mLastReceivedIntent;
        }
        
        public void clearReceivedIntents() {
            mLastReceivedIntent = null;
        }
    }
}
