/*
 * 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.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.
 */
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,
            float radius, int activityImportance) {
        try {
            if (!checkApiUsageLogCap()) {
                return;
            }

            boolean isLocationRequestNull = locationRequest == 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
                        + ", radius: " + radius
                        + ", 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),
                    bucketizeRadiusToStatsdEnum(radius),
                    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);
        }
    }
}
