/*
 * 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 com.android.server.twilight;

import com.android.server.SystemService;
import com.android.server.TwilightCalculator;

import android.app.AlarmManager;
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.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.text.format.DateUtils;
import android.text.format.Time;
import android.util.Slog;

import java.util.ArrayList;
import java.util.Iterator;

import libcore.util.Objects;

/**
 * Figures out whether it's twilight time based on the user's location.
 *
 * Used by the UI mode manager and other components to adjust night mode
 * effects based on sunrise and sunset.
 */
public final class TwilightService extends SystemService {
    static final String TAG = "TwilightService";
    static final boolean DEBUG = false;
    static final String ACTION_UPDATE_TWILIGHT_STATE =
            "com.android.server.action.UPDATE_TWILIGHT_STATE";

    final Object mLock = new Object();

    AlarmManager mAlarmManager;
    LocationManager mLocationManager;
    LocationHandler mLocationHandler;

    final ArrayList<TwilightListenerRecord> mListeners =
            new ArrayList<TwilightListenerRecord>();

    TwilightState mTwilightState;

    public TwilightService(Context context) {
        super(context);
    }

    @Override
    public void onStart() {
        mAlarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE);
        mLocationManager = (LocationManager) getContext().getSystemService(
                Context.LOCATION_SERVICE);
        mLocationHandler = new LocationHandler();

        IntentFilter filter = new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED);
        filter.addAction(Intent.ACTION_TIME_CHANGED);
        filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
        filter.addAction(ACTION_UPDATE_TWILIGHT_STATE);
        getContext().registerReceiver(mUpdateLocationReceiver, filter);

        publishLocalService(TwilightManager.class, mService);
    }

    private static class TwilightListenerRecord implements Runnable {
        private final TwilightListener mListener;
        private final Handler mHandler;

        public TwilightListenerRecord(TwilightListener listener, Handler handler) {
            mListener = listener;
            mHandler = handler;
        }

        public void postUpdate() {
            mHandler.post(this);
        }

        @Override
        public void run() {
            mListener.onTwilightStateChanged();
        }

    }

    private final TwilightManager mService = new TwilightManager() {
        /**
         * Gets the current twilight state.
         *
         * @return The current twilight state, or null if no information is available.
         */
        @Override
        public TwilightState getCurrentState() {
            synchronized (mLock) {
                return mTwilightState;
            }
        }

        /**
         * Listens for twilight time.
         *
         * @param listener The listener.
         */
        @Override
        public void registerListener(TwilightListener listener, Handler handler) {
            synchronized (mLock) {
                mListeners.add(new TwilightListenerRecord(listener, handler));

                if (mListeners.size() == 1) {
                    mLocationHandler.enableLocationUpdates();
                }
            }
        }
    };

    private void setTwilightState(TwilightState state) {
        synchronized (mLock) {
            if (!Objects.equal(mTwilightState, state)) {
                if (DEBUG) {
                    Slog.d(TAG, "Twilight state changed: " + state);
                }

                mTwilightState = state;

                final int listenerLen = mListeners.size();
                for (int i = 0; i < listenerLen; i++) {
                    mListeners.get(i).postUpdate();
                }
            }
        }
    }

    // The user has moved if the accuracy circles of the two locations don't overlap.
    private static boolean hasMoved(Location from, Location to) {
        if (to == null) {
            return false;
        }

        if (from == null) {
            return true;
        }

        // if new location is older than the current one, the device hasn't moved.
        if (to.getElapsedRealtimeNanos() < from.getElapsedRealtimeNanos()) {
            return false;
        }

        // Get the distance between the two points.
        float distance = from.distanceTo(to);

        // Get the total accuracy radius for both locations.
        float totalAccuracy = from.getAccuracy() + to.getAccuracy();

        // If the distance is greater than the combined accuracy of the two
        // points then they can't overlap and hence the user has moved.
        return distance >= totalAccuracy;
    }

    private final class LocationHandler extends Handler {
        private static final int MSG_ENABLE_LOCATION_UPDATES = 1;
        private static final int MSG_GET_NEW_LOCATION_UPDATE = 2;
        private static final int MSG_PROCESS_NEW_LOCATION = 3;
        private static final int MSG_DO_TWILIGHT_UPDATE = 4;

        private static final long LOCATION_UPDATE_MS = 24 * DateUtils.HOUR_IN_MILLIS;
        private static final long MIN_LOCATION_UPDATE_MS = 30 * DateUtils.MINUTE_IN_MILLIS;
        private static final float LOCATION_UPDATE_DISTANCE_METER = 1000 * 20;
        private static final long LOCATION_UPDATE_ENABLE_INTERVAL_MIN = 5000;
        private static final long LOCATION_UPDATE_ENABLE_INTERVAL_MAX =
                15 * DateUtils.MINUTE_IN_MILLIS;
        private static final double FACTOR_GMT_OFFSET_LONGITUDE =
                1000.0 * 360.0 / DateUtils.DAY_IN_MILLIS;

        private boolean mPassiveListenerEnabled;
        private boolean mNetworkListenerEnabled;
        private boolean mDidFirstInit;
        private long mLastNetworkRegisterTime = -MIN_LOCATION_UPDATE_MS;
        private long mLastUpdateInterval;
        private Location mLocation;
        private final TwilightCalculator mTwilightCalculator = new TwilightCalculator();

        public void processNewLocation(Location location) {
            Message msg = obtainMessage(MSG_PROCESS_NEW_LOCATION, location);
            sendMessage(msg);
        }

        public void enableLocationUpdates() {
            sendEmptyMessage(MSG_ENABLE_LOCATION_UPDATES);
        }

        public void requestLocationUpdate() {
            sendEmptyMessage(MSG_GET_NEW_LOCATION_UPDATE);
        }

        public void requestTwilightUpdate() {
            sendEmptyMessage(MSG_DO_TWILIGHT_UPDATE);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_PROCESS_NEW_LOCATION: {
                    final Location location = (Location)msg.obj;
                    final boolean hasMoved = hasMoved(mLocation, location);
                    final boolean hasBetterAccuracy = mLocation == null
                            || location.getAccuracy() < mLocation.getAccuracy();
                    if (DEBUG) {
                        Slog.d(TAG, "Processing new location: " + location
                               + ", hasMoved=" + hasMoved
                               + ", hasBetterAccuracy=" + hasBetterAccuracy);
                    }
                    if (hasMoved || hasBetterAccuracy) {
                        setLocation(location);
                    }
                    break;
                }

                case MSG_GET_NEW_LOCATION_UPDATE:
                    if (!mNetworkListenerEnabled) {
                        // Don't do anything -- we are still trying to get a
                        // location.
                        return;
                    }
                    if ((mLastNetworkRegisterTime + MIN_LOCATION_UPDATE_MS) >=
                            SystemClock.elapsedRealtime()) {
                        // Don't do anything -- it hasn't been long enough
                        // since we last requested an update.
                        return;
                    }

                    // Unregister the current location monitor, so we can
                    // register a new one for it to get an immediate update.
                    mNetworkListenerEnabled = false;
                    mLocationManager.removeUpdates(mEmptyLocationListener);

                    // Fall through to re-register listener.
                case MSG_ENABLE_LOCATION_UPDATES:
                    // enable network provider to receive at least location updates for a given
                    // distance.
                    boolean networkLocationEnabled;
                    try {
                        networkLocationEnabled =
                            mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
                    } catch (Exception e) {
                        // we may get IllegalArgumentException if network location provider
                        // does not exist or is not yet installed.
                        networkLocationEnabled = false;
                    }
                    if (!mNetworkListenerEnabled && networkLocationEnabled) {
                        mNetworkListenerEnabled = true;
                        mLastNetworkRegisterTime = SystemClock.elapsedRealtime();
                        mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
                                LOCATION_UPDATE_MS, 0, mEmptyLocationListener);

                        if (!mDidFirstInit) {
                            mDidFirstInit = true;
                            if (mLocation == null) {
                                retrieveLocation();
                            }
                        }
                    }

                    // enable passive provider to receive updates from location fixes (gps
                    // and network).
                    boolean passiveLocationEnabled;
                    try {
                        passiveLocationEnabled =
                            mLocationManager.isProviderEnabled(LocationManager.PASSIVE_PROVIDER);
                    } catch (Exception e) {
                        // we may get IllegalArgumentException if passive location provider
                        // does not exist or is not yet installed.
                        passiveLocationEnabled = false;
                    }

                    if (!mPassiveListenerEnabled && passiveLocationEnabled) {
                        mPassiveListenerEnabled = true;
                        mLocationManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER,
                                0, LOCATION_UPDATE_DISTANCE_METER , mLocationListener);
                    }

                    if (!(mNetworkListenerEnabled && mPassiveListenerEnabled)) {
                        mLastUpdateInterval *= 1.5;
                        if (mLastUpdateInterval == 0) {
                            mLastUpdateInterval = LOCATION_UPDATE_ENABLE_INTERVAL_MIN;
                        } else if (mLastUpdateInterval > LOCATION_UPDATE_ENABLE_INTERVAL_MAX) {
                            mLastUpdateInterval = LOCATION_UPDATE_ENABLE_INTERVAL_MAX;
                        }
                        sendEmptyMessageDelayed(MSG_ENABLE_LOCATION_UPDATES, mLastUpdateInterval);
                    }
                    break;

                case MSG_DO_TWILIGHT_UPDATE:
                    updateTwilightState();
                    break;
            }
        }

        private void retrieveLocation() {
            Location location = null;
            final Iterator<String> providers =
                    mLocationManager.getProviders(new Criteria(), true).iterator();
            while (providers.hasNext()) {
                final Location lastKnownLocation =
                        mLocationManager.getLastKnownLocation(providers.next());
                // pick the most recent location
                if (location == null || (lastKnownLocation != null &&
                        location.getElapsedRealtimeNanos() <
                        lastKnownLocation.getElapsedRealtimeNanos())) {
                    location = lastKnownLocation;
                }
            }

            // In the case there is no location available (e.g. GPS fix or network location
            // is not available yet), the longitude of the location is estimated using the timezone,
            // latitude and accuracy are set to get a good average.
            if (location == null) {
                Time currentTime = new Time();
                currentTime.set(System.currentTimeMillis());
                double lngOffset = FACTOR_GMT_OFFSET_LONGITUDE *
                        (currentTime.gmtoff - (currentTime.isDst > 0 ? 3600 : 0));
                location = new Location("fake");
                location.setLongitude(lngOffset);
                location.setLatitude(0);
                location.setAccuracy(417000.0f);
                location.setTime(System.currentTimeMillis());
                location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());

                if (DEBUG) {
                    Slog.d(TAG, "Estimated location from timezone: " + location);
                }
            }

            setLocation(location);
        }

        private void setLocation(Location location) {
            mLocation = location;
            updateTwilightState();
        }

        private void updateTwilightState() {
            if (mLocation == null) {
                setTwilightState(null);
                return;
            }

            final long now = System.currentTimeMillis();

            // calculate yesterday's twilight
            mTwilightCalculator.calculateTwilight(now - DateUtils.DAY_IN_MILLIS,
                    mLocation.getLatitude(), mLocation.getLongitude());
            final long yesterdaySunset = mTwilightCalculator.mSunset;

            // calculate today's twilight
            mTwilightCalculator.calculateTwilight(now,
                    mLocation.getLatitude(), mLocation.getLongitude());
            final boolean isNight = (mTwilightCalculator.mState == TwilightCalculator.NIGHT);
            final long todaySunrise = mTwilightCalculator.mSunrise;
            final long todaySunset = mTwilightCalculator.mSunset;

            // calculate tomorrow's twilight
            mTwilightCalculator.calculateTwilight(now + DateUtils.DAY_IN_MILLIS,
                    mLocation.getLatitude(), mLocation.getLongitude());
            final long tomorrowSunrise = mTwilightCalculator.mSunrise;

            // set twilight state
            TwilightState state = new TwilightState(isNight, yesterdaySunset,
                    todaySunrise, todaySunset, tomorrowSunrise);
            if (DEBUG) {
                Slog.d(TAG, "Updating twilight state: " + state);
            }
            setTwilightState(state);

            // schedule next update
            long nextUpdate = 0;
            if (todaySunrise == -1 || todaySunset == -1) {
                // In the case the day or night never ends the update is scheduled 12 hours later.
                nextUpdate = now + 12 * DateUtils.HOUR_IN_MILLIS;
            } else {
                // add some extra time to be on the safe side.
                nextUpdate += DateUtils.MINUTE_IN_MILLIS;

                if (now > todaySunset) {
                    nextUpdate += tomorrowSunrise;
                } else if (now > todaySunrise) {
                    nextUpdate += todaySunset;
                } else {
                    nextUpdate += todaySunrise;
                }
            }

            if (DEBUG) {
                Slog.d(TAG, "Next update in " + (nextUpdate - now) + " ms");
            }

            Intent updateIntent = new Intent(ACTION_UPDATE_TWILIGHT_STATE);
            PendingIntent pendingIntent = PendingIntent.getBroadcast(
                    getContext(), 0, updateIntent, 0);
            mAlarmManager.cancel(pendingIntent);
            mAlarmManager.setExact(AlarmManager.RTC, nextUpdate, pendingIntent);
        }
    }

    private final BroadcastReceiver mUpdateLocationReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(intent.getAction())
                    && !intent.getBooleanExtra("state", false)) {
                // Airplane mode is now off!
                mLocationHandler.requestLocationUpdate();
                return;
            }

            // Time zone has changed or alarm expired.
            mLocationHandler.requestTwilightUpdate();
        }
    };

    // A LocationListener to initialize the network location provider. The location updates
    // are handled through the passive location provider.
    private final LocationListener mEmptyLocationListener =  new LocationListener() {
        public void onLocationChanged(Location location) {
        }

        public void onProviderDisabled(String provider) {
        }

        public void onProviderEnabled(String provider) {
        }

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

    private final LocationListener mLocationListener = new LocationListener() {
        public void onLocationChanged(Location location) {
            mLocationHandler.processNewLocation(location);
        }

        public void onProviderDisabled(String provider) {
        }

        public void onProviderEnabled(String provider) {
        }

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