/*
 * Copyright (C) 2017 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.wallpaper.module;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.util.Log;

import com.android.wallpaper.model.WallpaperMetadata;
import com.android.wallpaper.module.WallpaperPreferences.PresentationMode;
import com.android.wallpaper.module.WallpaperRefresher.RefreshListener;
import com.android.wallpaper.util.DiskBasedLogger;

import java.util.Calendar;

import androidx.annotation.Nullable;

/**
 * Performs daily logging operations when alarm is received.
 */
public class DailyLoggingAlarmReceiver extends BroadcastReceiver {

    private static final String TAG = "DailyLoggingAlarm";

    /**
     * Releases the provided WakeLock if and only if it's currently held as to avoid throwing a
     * "WakeLock under-locked" RuntimeException.
     */
    private static void releaseWakeLock(WakeLock wakeLock) {
        if (wakeLock.isHeld()) {
            wakeLock.release();
        }
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        Context appContext = context.getApplicationContext();
        Injector injector = InjectorProvider.getInjector();
        UserEventLogger logger = injector.getUserEventLogger(appContext);
        WallpaperPreferences preferences = injector.getPreferences(appContext);

        logger.logNumDailyWallpaperRotationsInLastWeek();
        logger.logNumDailyWallpaperRotationsPreviousDay();
        logger.logWallpaperPresentationMode();
        logger.logSnapshot();

        preferences.setLastDailyLogTimestamp(System.currentTimeMillis());

        logDailyWallpaperRotationStatus(appContext);

        // Clear disk-based logs older than 7 days if they exist.
        DiskBasedLogger.clearOldLogs(appContext);
    }

    /**
     * If daily wallpapers are currently in effect and were enabled more than 24 hours ago, then log
     * the last-known rotation status as reported by the periodic background rotation components
     * (BackdropAlarmReceiver and BackdropRotationTask), or if there wasn't any status update in the
     * last 24 hours then log a "not attempted" status to the UserEventLogger.
     */
    private void logDailyWallpaperRotationStatus(Context appContext) {
        // Acquire a partial wakelock because logging the daily rotation requires doing some work on
        // another thread (via AsyncTask) after #onReceive returns, after which the kernel may power
        // down and prevent our daily rotation log from being sent.
        PowerManager powerManager = (PowerManager) appContext.getSystemService(Context.POWER_SERVICE);
        final WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
        wakeLock.acquire(10000 /* timeout */);

        final Injector injector = InjectorProvider.getInjector();

        // First check if rotation is still in effect.
        injector.getWallpaperRefresher(appContext).refresh(new RefreshListener() {
            @Override
            public void onRefreshed(WallpaperMetadata homeWallpaperMetadata,
                                    @Nullable WallpaperMetadata lockWallpaperMetadata,
                                    @PresentationMode int presentationMode) {
                // Don't log or do anything else if presentation mode is not rotating.
                if (presentationMode != WallpaperPreferences.PRESENTATION_MODE_ROTATING) {
                    releaseWakeLock(wakeLock);
                    return;
                }

                WallpaperPreferences preferences = injector.getPreferences(appContext);

                long dailyWallpaperEnabledTimestamp = preferences.getDailyWallpaperEnabledTimestamp();
                // Validate the daily wallpaper enabled timestamp.
                if (dailyWallpaperEnabledTimestamp < 0) {
                    Log.e(TAG, "There's no valid daily wallpaper enabled timestamp");
                    releaseWakeLock(wakeLock);
                    return;
                }

                Calendar midnightYesterday = Calendar.getInstance();
                midnightYesterday.add(Calendar.DAY_OF_MONTH, -1);
                midnightYesterday.set(Calendar.HOUR_OF_DAY, 0);
                midnightYesterday.set(Calendar.MINUTE, 0);

                // Exclude rotations that were put into affect later than midnight yesterday because the
                // background task may not have had a chance to execute yet.
                if (dailyWallpaperEnabledTimestamp > midnightYesterday.getTimeInMillis()) {
                    releaseWakeLock(wakeLock);
                    return;
                }

                try {
                    long lastRotationStatusTimestamp =
                            preferences.getDailyWallpaperLastRotationStatusTimestamp();

                    UserEventLogger logger = injector.getUserEventLogger(appContext);

                    // If a rotation status was reported more recently than midnight yesterday, then log it.
                    // Otherwise, log a "not attempted" rotation status.
                    if (lastRotationStatusTimestamp > midnightYesterday.getTimeInMillis()) {
                        int lastDailyWallpaperRotationStatus =
                                preferences.getDailyWallpaperLastRotationStatus();

                        logger.logDailyWallpaperRotationStatus(lastDailyWallpaperRotationStatus);

                        // If the daily rotation status is "failed", increment the num days failed in
                        // SharedPreferences and log it, otherwise reset the counter in SharedPreferences to 0.
                        if (UserEventLogger.ROTATION_STATUS_FAILED == lastDailyWallpaperRotationStatus) {
                            preferences.incrementNumDaysDailyRotationFailed();
                            logger.logNumDaysDailyRotationFailed(preferences.getNumDaysDailyRotationFailed());
                        } else {
                            preferences.resetNumDaysDailyRotationFailed();
                        }

                        // If there was a valid rotation status reported since midnight yesterday, then reset
                        // the counter for consecutive days of "not attempted".
                        preferences.resetNumDaysDailyRotationNotAttempted();
                    } else {
                        logger.logDailyWallpaperRotationStatus(UserEventLogger.ROTATION_STATUS_NOT_ATTEMPTED);

                        // Increment and log the consecutive # days in a row that daily rotation was not
                        // attempted.
                        preferences.incrementNumDaysDailyRotationNotAttempted();
                        logger.logNumDaysDailyRotationNotAttempted(
                                preferences.getNumDaysDailyRotationNotAttempted());

                        // Reset the disk-based counter for number of consecutive days daily rotation failed
                        // because if rotation was not attempted but restarts tomorrow after a boot and fails
                        // then, we want to report that as 1 day of failure instead of 3 consecutive days.
                        preferences.resetNumDaysDailyRotationFailed();
                    }
                } finally {
                    releaseWakeLock(wakeLock);
                }
            }
        });
    }
}
