/*
 * 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();
        logDailyActive(appContext);

        preferences.setLastDailyLogTimestamp(System.currentTimeMillis());

        logDailyWallpaperRotationStatus(appContext);

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

    private void logDailyActive(Context appContext) {
        Injector injector = InjectorProvider.getInjector();
        UserEventLogger logger = injector.getUserEventLogger(appContext);
        WallpaperPreferences preferences = injector.getPreferences(appContext);

        long lastAppLaunchTimestamp = preferences.getLastAppActiveTimestamp();

        Calendar calendar = Calendar.getInstance();
        // Subtract 28 days first to get a date 28 days ago to assess 28 day active, then add back
        // enough days to calculate 14 day active, 7 day active, and 1 day active.
        calendar.add(Calendar.DAY_OF_YEAR, -28);
        long twentyEightDaysAgo = calendar.getTimeInMillis();

        calendar.add(Calendar.DAY_OF_YEAR, 14);
        long fourteenDaysAgo = calendar.getTimeInMillis();

        calendar.add(Calendar.DAY_OF_YEAR, 7);
        long sevenDaysAgo = calendar.getTimeInMillis();

        calendar.add(Calendar.DAY_OF_YEAR, 6);
        long oneDayAgo = calendar.getTimeInMillis();

        if (lastAppLaunchTimestamp >= oneDayAgo) {
            logger.log1DayActive();
        }
        if (lastAppLaunchTimestamp >= sevenDaysAgo) {
            logger.log7DayActive();
        }
        if (lastAppLaunchTimestamp >= fourteenDaysAgo) {
            logger.log14DayActive();
        }
        if (lastAppLaunchTimestamp >= twentyEightDaysAgo) {
            logger.log28DayActive();
        }
    }

    /**
     * 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);
                }
            }
        });
    }
}
