package com.android.server.location;

import android.location.IGpsGeofenceHardware;
import android.util.Log;
import android.util.SparseArray;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;

/**
 * Manages GNSS Geofence operations.
 */
class GnssGeofenceProvider extends IGpsGeofenceHardware.Stub {

    private static final String TAG = "GnssGeofenceProvider";
    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);

    /** Holds the parameters of a geofence. */
    private static class GeofenceEntry {
        public int geofenceId;
        public double latitude;
        public double longitude;
        public double radius;
        public int lastTransition;
        public int monitorTransitions;
        public int notificationResponsiveness;
        public int unknownTimer;
        public boolean paused;
    }

    private final Object mLock = new Object();
    @GuardedBy("mLock")
    private final GnssGeofenceProviderNative mNative;
    @GuardedBy("mLock")
    private final SparseArray<GeofenceEntry> mGeofenceEntries = new SparseArray<>();

    GnssGeofenceProvider() {
        this(new GnssGeofenceProviderNative());
    }

    @VisibleForTesting
    GnssGeofenceProvider(GnssGeofenceProviderNative gnssGeofenceProviderNative) {
        mNative = gnssGeofenceProviderNative;
    }

    void resumeIfStarted() {
        if (DEBUG) {
            Log.d(TAG, "resumeIfStarted");
        }
        synchronized (mLock) {
            for (int i = 0; i < mGeofenceEntries.size(); i++) {
                GeofenceEntry entry = mGeofenceEntries.valueAt(i);
                boolean added = mNative.addGeofence(entry.geofenceId, entry.latitude,
                        entry.longitude,
                        entry.radius,
                        entry.lastTransition, entry.monitorTransitions,
                        entry.notificationResponsiveness, entry.unknownTimer);
                if (added && entry.paused) {
                    mNative.pauseGeofence(entry.geofenceId);
                }
            }
        }
    }

    @Override
    public boolean isHardwareGeofenceSupported() {
        synchronized (mLock) {
            return mNative.isGeofenceSupported();
        }
    }

    @Override
    public boolean addCircularHardwareGeofence(int geofenceId, double latitude,
            double longitude, double radius, int lastTransition, int monitorTransitions,
            int notificationResponsiveness, int unknownTimer) {
        synchronized (mLock) {
            boolean added = mNative.addGeofence(geofenceId, latitude, longitude, radius,
                    lastTransition, monitorTransitions, notificationResponsiveness,
                    unknownTimer);
            if (added) {
                GeofenceEntry entry = new GeofenceEntry();
                entry.geofenceId = geofenceId;
                entry.latitude = latitude;
                entry.longitude = longitude;
                entry.radius = radius;
                entry.lastTransition = lastTransition;
                entry.monitorTransitions = monitorTransitions;
                entry.notificationResponsiveness = notificationResponsiveness;
                entry.unknownTimer = unknownTimer;
                mGeofenceEntries.put(geofenceId, entry);
            }
            return added;
        }
    }

    @Override
    public boolean removeHardwareGeofence(int geofenceId) {
        synchronized (mLock) {
            boolean removed = mNative.removeGeofence(geofenceId);
            if (removed) {
                mGeofenceEntries.remove(geofenceId);
            }
            return removed;
        }
    }

    @Override
    public boolean pauseHardwareGeofence(int geofenceId) {
        synchronized (mLock) {
            boolean paused = mNative.pauseGeofence(geofenceId);
            if (paused) {
                GeofenceEntry entry = mGeofenceEntries.get(geofenceId);
                if (entry != null) {
                    entry.paused = true;
                }
            }
            return paused;
        }
    }

    @Override
    public boolean resumeHardwareGeofence(int geofenceId, int monitorTransitions) {
        synchronized (mLock) {
            boolean resumed = mNative.resumeGeofence(geofenceId, monitorTransitions);
            if (resumed) {
                GeofenceEntry entry = mGeofenceEntries.get(geofenceId);
                if (entry != null) {
                    entry.paused = false;
                    entry.monitorTransitions = monitorTransitions;
                }
            }
            return resumed;
        }
    }

    @VisibleForTesting
    static class GnssGeofenceProviderNative {
        public boolean isGeofenceSupported() {
            return native_is_geofence_supported();
        }

        public boolean addGeofence(int geofenceId, double latitude, double longitude, double radius,
                int lastTransition, int monitorTransitions, int notificationResponsiveness,
                int unknownTimer) {
            return native_add_geofence(geofenceId, latitude, longitude, radius, lastTransition,
                    monitorTransitions, notificationResponsiveness, unknownTimer);
        }

        public boolean removeGeofence(int geofenceId) {
            return native_remove_geofence(geofenceId);
        }

        public boolean resumeGeofence(int geofenceId, int transitions) {
            return native_resume_geofence(geofenceId, transitions);
        }

        public boolean pauseGeofence(int geofenceId) {
            return native_pause_geofence(geofenceId);
        }
    }

    private static native boolean native_is_geofence_supported();

    private static native boolean native_add_geofence(int geofenceId, double latitude,
            double longitude, double radius, int lastTransition, int monitorTransitions,
            int notificationResponsivenes, int unknownTimer);

    private static native boolean native_remove_geofence(int geofenceId);

    private static native boolean native_resume_geofence(int geofenceId, int transitions);

    private static native boolean native_pause_geofence(int geofenceId);
}
