/*
 * Copyright (C) 2016 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.storagemanager.automatic;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.os.SystemProperties;
import android.provider.Settings;

import com.android.storagemanager.R;
import com.android.storagemanager.automatic.WarningDialogActivity;
import com.android.storagemanager.overlay.FeatureFactory;

import java.util.concurrent.TimeUnit;

/**
 * NotificationController handles the responses to the Automatic Storage Management low storage
 * notification.
 */
public class NotificationController extends BroadcastReceiver {
    /**
     * Intent action for if the user taps "Turn on" for the automatic storage manager.
     */
    public static final String INTENT_ACTION_ACTIVATE_ASM =
            "com.android.storagemanager.automatic.ACTIVATE";

    /**
     * Intent action for if the user swipes the notification away.
     */
    public static final String INTENT_ACTION_DISMISS =
            "com.android.storagemanager.automatic.DISMISS";

    /**
     * Intent action for if the user explicitly hits "No thanks" on the notification.
     */
    public static final String INTENT_ACTION_NO_THANKS =
            "com.android.storagemanager.automatic.NO_THANKS";

    /**
     * Intent action for forcefully showing the notification, even if the conditions are not valid.
     */
    private static final String INTENT_ACTION_DEBUG_NOTIFICATION =
            "com.android.storagemanager.automatic.DEBUG_SHOW_NOTIFICATION";

    /**
     * Intent action for if the user taps on the notification.
     */
    private static final String INTENT_ACTION_TAP =
            "com.android.storagemanager.automatic.SHOW_SETTINGS";

    /**
     * Intent extra for the notification id.
     */
    public static final String INTENT_EXTRA_ID = "id";

    private static final String SHARED_PREFERENCES_NAME = "NotificationController";
    private static final String NOTIFICATION_NEXT_SHOW_TIME = "notification_next_show_time";
    private static final String NOTIFICATION_SHOWN_COUNT = "notification_shown_count";
    private static final String NOTIFICATION_DISMISS_COUNT = "notification_dismiss_count";
    private static final String STORAGE_MANAGER_PROPERTY = "ro.storage_manager.enabled";

    private static final long DISMISS_DELAY = TimeUnit.DAYS.toMillis(15);
    private static final long NO_THANKS_DELAY = TimeUnit.DAYS.toMillis(90);
    private static final long MAXIMUM_SHOWN_COUNT = 4;
    private static final long MAXIMUM_DISMISS_COUNT = 9;
    private static final int NOTIFICATION_ID = 0;

    @Override
    public void onReceive(Context context, Intent intent) {
        switch (intent.getAction()) {
            case INTENT_ACTION_ACTIVATE_ASM:
                Settings.Secure.putInt(context.getContentResolver(),
                        Settings.Secure.AUTOMATIC_STORAGE_MANAGER_ENABLED,
                        1);
                // Provide a warning if storage manager is not defaulted on.
                if (!SystemProperties.getBoolean(STORAGE_MANAGER_PROPERTY, false)) {
                    Intent warningIntent = new Intent(context, WarningDialogActivity.class);
                    context.startActivity(warningIntent);
                }
                break;
            case INTENT_ACTION_NO_THANKS:
                delayNextNotification(context, NO_THANKS_DELAY);
                break;
            case INTENT_ACTION_DISMISS:
                delayNextNotification(context, DISMISS_DELAY);
                break;
            case INTENT_ACTION_DEBUG_NOTIFICATION:
                showNotification(context);
                return;
            case INTENT_ACTION_TAP:
                Intent storageIntent = new Intent(Settings.ACTION_STORAGE_MANAGER_SETTINGS);
                storageIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity(storageIntent);
                break;
        }
        cancelNotification(context, intent);
    }

    /**
     * If the conditions for showing the activation notification are met, show the activation
     * notification.
     * @param context Context to use for getting resources and to display the notification.
     */
    public static void maybeShowNotification(Context context) {
        if (shouldShowNotification(context)) {
            showNotification(context);
        }
    }

    private static boolean shouldShowNotification(Context context) {
        SharedPreferences sp = context.getSharedPreferences(
                SHARED_PREFERENCES_NAME,
                Context.MODE_PRIVATE);
        int timesShown = sp.getInt(NOTIFICATION_SHOWN_COUNT, 0);
        int timesDismissed = sp.getInt(NOTIFICATION_DISMISS_COUNT, 0);
        if (timesShown >= MAXIMUM_SHOWN_COUNT || timesDismissed >= MAXIMUM_DISMISS_COUNT) {
            return false;
        }

        long nextTimeToShow = sp.getLong(NOTIFICATION_NEXT_SHOW_TIME, 0);

        return System.currentTimeMillis() > nextTimeToShow;
    }

    private static void showNotification(Context context) {
        Resources res = context.getResources();
        Intent noThanksIntent = new Intent(INTENT_ACTION_NO_THANKS);
        noThanksIntent.putExtra(INTENT_EXTRA_ID, NOTIFICATION_ID);
        Notification.Action.Builder cancelAction = new Notification.Action.Builder(null,
                res.getString(R.string.automatic_storage_manager_cancel_button),
                PendingIntent.getBroadcast(context, 0, noThanksIntent,
                        PendingIntent.FLAG_UPDATE_CURRENT));


        Intent activateIntent = new Intent(INTENT_ACTION_ACTIVATE_ASM);
        activateIntent.putExtra(INTENT_EXTRA_ID, NOTIFICATION_ID);
        Notification.Action.Builder activateAutomaticAction = new Notification.Action.Builder(null,
                res.getString(R.string.automatic_storage_manager_activate_button),
                PendingIntent.getBroadcast(context, 0, activateIntent,
                        PendingIntent.FLAG_UPDATE_CURRENT));

        Intent dismissIntent = new Intent(INTENT_ACTION_DISMISS);
        dismissIntent.putExtra(INTENT_EXTRA_ID, NOTIFICATION_ID);
        PendingIntent deleteIntent = PendingIntent.getBroadcast(context, 0,
                dismissIntent,
                PendingIntent.FLAG_ONE_SHOT);

        Intent contentIntent = new Intent(INTENT_ACTION_TAP);
        contentIntent.putExtra(INTENT_EXTRA_ID, NOTIFICATION_ID);
        PendingIntent tapIntent = PendingIntent.getBroadcast(context, 0,  contentIntent,
                PendingIntent.FLAG_ONE_SHOT);

        Notification.Builder builder = new Notification.Builder(context)
                .setSmallIcon(R.drawable.ic_settings_24dp)
                .setContentTitle(
                        res.getString(R.string.automatic_storage_manager_notification_title))
                .setContentText(
                        res.getString(R.string.automatic_storage_manager_notification_summary))
                .setStyle(new Notification.BigTextStyle().bigText(
                        res.getString(R.string.automatic_storage_manager_notification_summary)))
                .addAction(cancelAction.build())
                .addAction(activateAutomaticAction.build())
                .setContentIntent(tapIntent)
                .setDeleteIntent(deleteIntent);

        NotificationManager manager =
                ((NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE));
        manager.notify(NOTIFICATION_ID, builder.build());
    }

    private void cancelNotification(Context context, Intent intent) {
        if (intent.getAction() == INTENT_ACTION_DISMISS) {
            incrementNotificationDismissedCount(context);
        } else {
            incrementNotificationShownCount(context);
        }

        int id = intent.getIntExtra(INTENT_EXTRA_ID, -1);
        if (id == -1) {
            return;
        }
        NotificationManager manager = (NotificationManager) context
                .getSystemService(Context.NOTIFICATION_SERVICE);
        manager.cancel(id);
    }

    private void incrementNotificationShownCount(Context context) {
        SharedPreferences sp = context.getSharedPreferences(SHARED_PREFERENCES_NAME,
                Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        int shownCount = sp.getInt(NotificationController.NOTIFICATION_SHOWN_COUNT, 0) + 1;
        editor.putInt(NotificationController.NOTIFICATION_SHOWN_COUNT, shownCount);
        editor.apply();
    }

    private void incrementNotificationDismissedCount(Context context) {
        SharedPreferences sp = context.getSharedPreferences(SHARED_PREFERENCES_NAME,
                Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        int dismissCount = sp.getInt(NOTIFICATION_DISMISS_COUNT, 0) + 1;
        editor.putInt(NOTIFICATION_DISMISS_COUNT, dismissCount);
        editor.apply();
    }

    private void delayNextNotification(Context context, long timeInMillis) {
        SharedPreferences sp = context.getSharedPreferences(SHARED_PREFERENCES_NAME,
                Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.putLong(NOTIFICATION_NEXT_SHOW_TIME,
                System.currentTimeMillis() + timeInMillis);
        editor.apply();
    }
}
