/*
 * Copyright (C) 2019 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;

import android.app.ActivityManager;
import android.location.Geofence;
import android.location.LocationManager;
import android.location.LocationRequest;
import android.os.SystemClock;
import android.stats.location.LocationStatsEnums;
import android.util.Log;
import android.util.StatsLog;

import java.time.Instant;

/**
 * Logger for Location API usage logging.
 */
public class LocationUsageLogger {
    private static final String TAG = "LocationUsageLogger";
    private static final boolean D = Log.isLoggable(TAG, Log.DEBUG);

    private static final int ONE_SEC_IN_MILLIS = 1000;
    private static final int ONE_MINUTE_IN_MILLIS = 60000;
    private static final int ONE_HOUR_IN_MILLIS = 3600000;

    private long mLastApiUsageLogHour = 0;

    private int mApiUsageLogHourlyCount = 0;

    private static final int API_USAGE_LOG_HOURLY_CAP = 60;

    private static int providerNameToStatsdEnum(String provider) {
        if (LocationManager.NETWORK_PROVIDER.equals(provider)) {
            return LocationStatsEnums.PROVIDER_NETWORK;
        } else if (LocationManager.GPS_PROVIDER.equals(provider)) {
            return LocationStatsEnums.PROVIDER_GPS;
        } else if (LocationManager.PASSIVE_PROVIDER.equals(provider)) {
            return LocationStatsEnums.PROVIDER_PASSIVE;
        } else if (LocationManager.FUSED_PROVIDER.equals(provider)) {
            return LocationStatsEnums.PROVIDER_FUSED;
        } else {
            return LocationStatsEnums.PROVIDER_UNKNOWN;
        }
    }

    private static int bucketizeIntervalToStatsdEnum(long interval) {
        // LocationManager already converts negative values to 0.
        if (interval < ONE_SEC_IN_MILLIS) {
            return LocationStatsEnums.INTERVAL_BETWEEN_0_SEC_AND_1_SEC;
        } else if (interval < ONE_SEC_IN_MILLIS * 5) {
            return LocationStatsEnums.INTERVAL_BETWEEN_1_SEC_AND_5_SEC;
        } else if (interval < ONE_MINUTE_IN_MILLIS) {
            return LocationStatsEnums.INTERVAL_BETWEEN_5_SEC_AND_1_MIN;
        } else if (interval < ONE_MINUTE_IN_MILLIS * 10) {
            return LocationStatsEnums.INTERVAL_BETWEEN_1_MIN_AND_10_MIN;
        } else if (interval < ONE_HOUR_IN_MILLIS) {
            return LocationStatsEnums.INTERVAL_BETWEEN_10_MIN_AND_1_HOUR;
        } else {
            return LocationStatsEnums.INTERVAL_LARGER_THAN_1_HOUR;
        }
    }

    private static int bucketizeSmallestDisplacementToStatsdEnum(float smallestDisplacement) {
        // LocationManager already converts negative values to 0.
        if (smallestDisplacement == 0) {
            return LocationStatsEnums.DISTANCE_ZERO;
        } else if (smallestDisplacement > 0 && smallestDisplacement <= 100) {
            return LocationStatsEnums.DISTANCE_BETWEEN_0_AND_100;
        } else {
            return LocationStatsEnums.DISTANCE_LARGER_THAN_100;
        }
    }

    private static int bucketizeRadiusToStatsdEnum(float radius) {
        if (radius < 0) {
            return LocationStatsEnums.RADIUS_NEGATIVE;
        } else if (radius < 100) {
            return LocationStatsEnums.RADIUS_BETWEEN_0_AND_100;
        } else if (radius < 200) {
            return LocationStatsEnums.RADIUS_BETWEEN_100_AND_200;
        } else if (radius < 300) {
            return LocationStatsEnums.RADIUS_BETWEEN_200_AND_300;
        } else if (radius < 1000) {
            return LocationStatsEnums.RADIUS_BETWEEN_300_AND_1000;
        } else if (radius < 10000) {
            return LocationStatsEnums.RADIUS_BETWEEN_1000_AND_10000;
        } else {
            return LocationStatsEnums.RADIUS_LARGER_THAN_100000;
        }
    }

    private static int getBucketizedExpireIn(long expireAt) {
        if (expireAt == Long.MAX_VALUE) {
            return LocationStatsEnums.EXPIRATION_NO_EXPIRY;
        }

        long elapsedRealtime = SystemClock.elapsedRealtime();
        long expireIn = Math.max(0, expireAt - elapsedRealtime);

        if (expireIn < 20 * ONE_SEC_IN_MILLIS) {
            return LocationStatsEnums.EXPIRATION_BETWEEN_0_AND_20_SEC;
        } else if (expireIn < ONE_MINUTE_IN_MILLIS) {
            return LocationStatsEnums.EXPIRATION_BETWEEN_20_SEC_AND_1_MIN;
        } else if (expireIn < ONE_MINUTE_IN_MILLIS * 10) {
            return LocationStatsEnums.EXPIRATION_BETWEEN_1_MIN_AND_10_MIN;
        } else if (expireIn < ONE_HOUR_IN_MILLIS) {
            return LocationStatsEnums.EXPIRATION_BETWEEN_10_MIN_AND_1_HOUR;
        } else {
            return LocationStatsEnums.EXPIRATION_LARGER_THAN_1_HOUR;
        }
    }

    private static int categorizeActivityImportance(int importance) {
        if (importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
            return LocationStatsEnums.IMPORTANCE_TOP;
        } else if (importance == ActivityManager
                                    .RunningAppProcessInfo
                                    .IMPORTANCE_FOREGROUND_SERVICE) {
            return LocationStatsEnums.IMPORTANCE_FORGROUND_SERVICE;
        } else {
            return LocationStatsEnums.IMPORTANCE_BACKGROUND;
        }
    }

    private static int getCallbackType(
            int apiType, boolean hasListener, boolean hasIntent) {
        if (apiType == LocationStatsEnums.API_SEND_EXTRA_COMMAND) {
            return LocationStatsEnums.CALLBACK_NOT_APPLICABLE;
        }

        // Listener and PendingIntent will not be set at
        // the same time.
        if (hasIntent) {
            return LocationStatsEnums.CALLBACK_PENDING_INTENT;
        } else if (hasListener) {
            return LocationStatsEnums.CALLBACK_LISTENER;
        } else {
            return LocationStatsEnums.CALLBACK_UNKNOWN;
        }
    }

    // Update the hourly count of APIUsage log event.
    // Returns false if hit the hourly log cap.
    private boolean checkApiUsageLogCap() {
        if (D) {
            Log.d(TAG, "checking APIUsage log cap.");
        }

        long currentHour = Instant.now().toEpochMilli() / ONE_HOUR_IN_MILLIS;
        if (currentHour > mLastApiUsageLogHour) {
            mLastApiUsageLogHour = currentHour;
            mApiUsageLogHourlyCount = 0;
            return true;
        } else {
            mApiUsageLogHourlyCount = Math.min(
                mApiUsageLogHourlyCount + 1, API_USAGE_LOG_HOURLY_CAP);
            return mApiUsageLogHourlyCount < API_USAGE_LOG_HOURLY_CAP;
        }
    }

    /**
     * Log a Location API usage event to Statsd.
     * Logging event is capped at 60 per hour. Usage events exceeding
     * the cap will be dropped by LocationUsageLogger.
     */
    public void logLocationApiUsage(int usageType, int apiInUse,
            String packageName, LocationRequest locationRequest,
            boolean hasListener, boolean hasIntent,
            Geofence geofence, int activityImportance) {
        try {
            if (!checkApiUsageLogCap()) {
                return;
            }

            boolean isLocationRequestNull = locationRequest == null;
            boolean isGeofenceNull = geofence == null;
            if (D) {
                Log.d(TAG, "log API Usage to statsd. usageType: " + usageType + ", apiInUse: "
                        + apiInUse + ", packageName: " + (packageName == null ? "" : packageName)
                        + ", locationRequest: "
                        + (isLocationRequestNull ? "" : locationRequest.toString())
                        + ", hasListener: " + hasListener
                        + ", hasIntent: " + hasIntent
                        + ", geofence: "
                        + (isGeofenceNull ? "" : geofence.toString())
                        + ", importance: " + activityImportance);
            }

            StatsLog.write(StatsLog.LOCATION_MANAGER_API_USAGE_REPORTED, usageType,
                    apiInUse, packageName,
                    isLocationRequestNull
                        ? LocationStatsEnums.PROVIDER_UNKNOWN
                        : providerNameToStatsdEnum(locationRequest.getProvider()),
                    isLocationRequestNull
                        ? LocationStatsEnums.QUALITY_UNKNOWN
                        : locationRequest.getQuality(),
                    isLocationRequestNull
                        ? LocationStatsEnums.INTERVAL_UNKNOWN
                        : bucketizeIntervalToStatsdEnum(locationRequest.getInterval()),
                    isLocationRequestNull
                        ? LocationStatsEnums.DISTANCE_UNKNOWN
                        : bucketizeSmallestDisplacementToStatsdEnum(
                                locationRequest.getSmallestDisplacement()),
                    isLocationRequestNull ? 0 : locationRequest.getNumUpdates(),
                    // only log expireIn for USAGE_STARTED
                    isLocationRequestNull || usageType == LocationStatsEnums.USAGE_ENDED
                        ? LocationStatsEnums.EXPIRATION_UNKNOWN
                        : getBucketizedExpireIn(locationRequest.getExpireAt()),
                    getCallbackType(apiInUse, hasListener, hasIntent),
                    isGeofenceNull
                        ? LocationStatsEnums.RADIUS_UNKNOWN
                        : bucketizeRadiusToStatsdEnum(geofence.getRadius()),
                    categorizeActivityImportance(activityImportance));
        } catch (Exception e) {
            // Swallow exceptions to avoid crashing LMS.
            Log.w(TAG, "Failed to log API usage to statsd.", e);
        }
    }

    /**
     * Log a Location API usage event to Statsd.
     * Logging event is capped at 60 per hour. Usage events exceeding
     * the cap will be dropped by LocationUsageLogger.
     */
    public void logLocationApiUsage(int usageType, int apiInUse, String providerName) {
        try {
            if (!checkApiUsageLogCap()) {
                return;
            }

            if (D) {
                Log.d(TAG, "log API Usage to statsd. usageType: " + usageType + ", apiInUse: "
                        + apiInUse + ", providerName: " + providerName);
            }

            StatsLog.write(StatsLog.LOCATION_MANAGER_API_USAGE_REPORTED, usageType, apiInUse,
                    /* package_name= */ null,
                    providerNameToStatsdEnum(providerName),
                    LocationStatsEnums.QUALITY_UNKNOWN,
                    LocationStatsEnums.INTERVAL_UNKNOWN,
                    LocationStatsEnums.DISTANCE_UNKNOWN,
                    /* numUpdates= */ 0,
                    LocationStatsEnums.EXPIRATION_UNKNOWN,
                    getCallbackType(
                            apiInUse,
                            /* isListenerNull= */ true,
                            /* isIntentNull= */ true),
                    /* bucketizedRadius= */ 0,
                    LocationStatsEnums.IMPORTANCE_UNKNOWN);
        } catch (Exception e) {
            // Swallow exceptions to avoid crashing LMS.
            Log.w(TAG, "Failed to log API usage to statsd.", e);
        }
    }
}
