/*
 * Copyright (C) 2012 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.bordeaux.services;

import android.content.Context;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.os.Process;
import android.util.Log;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

// TODO: add functionality to detect speed (use GPS) when needed
// withouth draining the battery quickly
public class LocationStatsAggregator extends Aggregator {
    final String TAG = "LocationStatsAggregator";
    public static final String CURRENT_LOCATION = "Current Location";
    public static final String CURRENT_SPEED = "Current Speed";
    public static final String UNKNOWN_LOCATION = "Unknown Location";

    // TODO: Collect location on every minute (60000 milliseconds)
    private static final long MINIMUM_TIME = 60000;

    // reset best location provider on every 10 minutes (300000 milliseconds)
    private static final int BEST_PROVIDER_DURATION = 600000;

    private static final float MINIMUM_DISTANCE = 0f; // meter

    private static final int LOCATION_CHANGE = 1;

    // record time when the location provider is set
    private long mProviderSetTime;

    private Handler mHandler;
    private HandlerThread mHandlerThread;
    private LocationManager mLocationManager;
    private ClusterManager mClusterManager;

    // Fake location, used for testing.
    private String mFakeLocation = null;

    public LocationStatsAggregator(final Context context) {
        mLocationManager =
            (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
        setClusteringThread(context);
        requestLocationUpdate();
    }

    public String[] getListOfFeatures(){
        String[] list = { CURRENT_LOCATION } ;
        return list;
    }

    public Map<String,String> getFeatureValue(String featureName) {
        HashMap<String,String> feature = new HashMap<String,String>();

        if (featureName.equals(CURRENT_LOCATION)) {
            // TODO: check last known location first before sending out location request.
            /*
              Location location =
              mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
            */
            String location = mClusterManager.getSemanticLocation();
            if (!location.equals(UNKNOWN_LOCATION)) {
                if (mFakeLocation != null) {
                    feature.put(CURRENT_LOCATION, mFakeLocation);
                } else {
                    feature.put(CURRENT_LOCATION, location);
                }
            }
        }
        return (Map) feature;
    }

    public List<String> getClusterNames() {
        return mClusterManager.getClusterNames();
    }

    // set a fake location using cluster name.
    // Set an empty string "" to disable the fake location
    public void setFakeLocation(String name) {
        if (name != null && name.length() != 0)
            mFakeLocation = name;
        else mFakeLocation = null;
    }

    private void setClusteringThread(Context context) {
        mClusterManager = new ClusterManager(context);

        mHandlerThread = new HandlerThread("Location Handler",
                Process.THREAD_PRIORITY_BACKGROUND);
        mHandlerThread.start();
        mHandler = new Handler(mHandlerThread.getLooper()) {

            @Override
            public void handleMessage(Message msg) {
                if (!(msg.obj instanceof Location)) {
                    return;
                }
                Location location = (Location) msg.obj;
                switch(msg.what) {
                    case LOCATION_CHANGE:
                        mClusterManager.addSample(location);
                        break;
                    default:
                        super.handleMessage(msg);
                }
            }
        };
    }

    private void requestLocationUpdate() {
        Criteria criteria = new Criteria();
        criteria.setAccuracy(Criteria.ACCURACY_COARSE);
        criteria.setPowerRequirement(Criteria.POWER_LOW);
        /*
        criteria.setAltitudeRequired(false);
        criteria.setBearingRequired(false);
        criteria.setSpeedRequired(true);
        */
        criteria.setCostAllowed(true);

        String bestProvider = mLocationManager.getBestProvider(criteria, false);
        Log.i(TAG, "Best Location Provider: " + bestProvider);

        String bestAvailableProvider = mLocationManager.getBestProvider(criteria, true);
        Log.i(TAG, "Best Available Location Provider: " + bestAvailableProvider);

        mProviderSetTime = System.currentTimeMillis();
        if (bestAvailableProvider != null) {
            mLocationManager.requestLocationUpdates(
                bestAvailableProvider, MINIMUM_TIME, MINIMUM_DISTANCE, mLocationListener);
        }
    }

    private final LocationListener mLocationListener = new LocationListener() {
        public void onLocationChanged(Location location) {
            long currentTime = location.getTime();
            if (currentTime - mProviderSetTime < MINIMUM_TIME) {
                return;
            }
            mHandler.sendMessage(mHandler.obtainMessage(LOCATION_CHANGE, location));
            // search again for the location service
            if (currentTime - mProviderSetTime > BEST_PROVIDER_DURATION) {
                mLocationManager.removeUpdates(this);
                Log.e(TAG, "reselect best location provider");
                requestLocationUpdate();
            }
        }

        public void onStatusChanged(String provider, int status, Bundle extras) { }

        public void onProviderEnabled(String provider) { }

        public void onProviderDisabled(String provider) { }
    };
}
