/*
 * Copyright 2018 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.wifi;

import static com.android.server.wifi.WakeupNotificationFactory.ACTION_DISMISS_NOTIFICATION;
import static com.android.server.wifi.WakeupNotificationFactory.ACTION_OPEN_WIFI_PREFERENCES;
import static com.android.server.wifi.WakeupNotificationFactory.ACTION_TURN_OFF_WIFI_WAKE;

import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
import android.os.SystemClock;
import android.provider.Settings;
import android.text.format.DateUtils;
import android.util.Log;

import com.android.internal.annotations.VisibleForTesting;

/**
 * Manages the WiFi Wake onboarding notification.
 *
 * <p>If a user disables wifi with Wifi Wake enabled, this notification is shown to explain that
 * wifi may turn back on automatically. It will be displayed up to 3 times, or until the
 * user either interacts with the onboarding notification in some way (e.g. dismiss, tap) or
 * manually enables/disables the feature in WifiSettings.
 */
public class WakeupOnboarding {

    private static final String TAG = "WakeupOnboarding";

    @VisibleForTesting
    static final int NOTIFICATIONS_UNTIL_ONBOARDED = 3;
    @VisibleForTesting
    static final long REQUIRED_NOTIFICATION_DELAY = DateUtils.DAY_IN_MILLIS;
    private static final long NOT_SHOWN_TIMESTAMP = -1;

    private final Context mContext;
    private final WakeupNotificationFactory mWakeupNotificationFactory;
    private NotificationManager mNotificationManager;
    private final Handler mHandler;
    private final WifiConfigManager mWifiConfigManager;
    private final IntentFilter mIntentFilter;
    private final FrameworkFacade mFrameworkFacade;

    private boolean mIsOnboarded;
    private int mTotalNotificationsShown;
    private long mLastShownTimestamp = NOT_SHOWN_TIMESTAMP;
    private boolean mIsNotificationShowing;

    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            switch (intent.getAction()) {
                case ACTION_TURN_OFF_WIFI_WAKE:
                    mFrameworkFacade.setIntegerSetting(mContext,
                            Settings.Global.WIFI_WAKEUP_ENABLED, 0);
                    dismissNotification(true /* shouldOnboard */);
                    break;
                case ACTION_OPEN_WIFI_PREFERENCES:
                    // Close notification drawer before opening preferences.
                    mContext.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
                    mContext.startActivity(new Intent(Settings.ACTION_WIFI_IP_SETTINGS)
                            .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
                    dismissNotification(true /* shouldOnboard */);
                    break;
                case ACTION_DISMISS_NOTIFICATION:
                    dismissNotification(true /* shouldOnboard */);
                    break;
                default:
                    Log.e(TAG, "Unknown action " + intent.getAction());
            }
        }
    };

    public WakeupOnboarding(
            Context context,
            WifiConfigManager wifiConfigManager,
            Handler handler,
            FrameworkFacade frameworkFacade,
            WakeupNotificationFactory wakeupNotificationFactory) {
        mContext = context;
        mWifiConfigManager = wifiConfigManager;
        mHandler = handler;
        mFrameworkFacade = frameworkFacade;
        mWakeupNotificationFactory = wakeupNotificationFactory;

        mIntentFilter = new IntentFilter();
        mIntentFilter.addAction(ACTION_TURN_OFF_WIFI_WAKE);
        mIntentFilter.addAction(ACTION_DISMISS_NOTIFICATION);
        mIntentFilter.addAction(ACTION_OPEN_WIFI_PREFERENCES);
    }

    /** Returns whether the user is onboarded. */
    public boolean isOnboarded() {
        return mIsOnboarded;
    }

    /** Shows the onboarding notification if applicable. */
    public void maybeShowNotification() {
        maybeShowNotification(SystemClock.elapsedRealtime());
    }

    @VisibleForTesting
    void maybeShowNotification(long timestamp) {
        if (!shouldShowNotification(timestamp)) {
            return;
        }
        Log.d(TAG, "Showing onboarding notification.");

        incrementTotalNotificationsShown();
        mIsNotificationShowing = true;
        mLastShownTimestamp = timestamp;

        mContext.registerReceiver(mBroadcastReceiver, mIntentFilter,
                null /* broadcastPermission */, mHandler);
        getNotificationManager().notify(WakeupNotificationFactory.ONBOARD_ID,
                mWakeupNotificationFactory.createOnboardingNotification());
    }

    /**
     * Increment the total number of shown notifications and onboard the user if reached the
     * required amount.
     */
    private void incrementTotalNotificationsShown() {
        mTotalNotificationsShown++;
        if (mTotalNotificationsShown >= NOTIFICATIONS_UNTIL_ONBOARDED) {
            setOnboarded();
        } else {
            mWifiConfigManager.saveToStore(false /* forceWrite */);
        }
    }

    private boolean shouldShowNotification(long timestamp) {
        if (isOnboarded() || mIsNotificationShowing) {
            return false;
        }

        return mLastShownTimestamp == NOT_SHOWN_TIMESTAMP
                || (timestamp - mLastShownTimestamp) > REQUIRED_NOTIFICATION_DELAY;
    }

    /** Handles onboarding cleanup on stop. */
    public void onStop() {
        dismissNotification(false /* shouldOnboard */);
    }

    private void dismissNotification(boolean shouldOnboard) {
        if (!mIsNotificationShowing) {
            return;
        }

        if (shouldOnboard) {
            setOnboarded();
        }

        mContext.unregisterReceiver(mBroadcastReceiver);
        getNotificationManager().cancel(WakeupNotificationFactory.ONBOARD_ID);
        mIsNotificationShowing = false;
    }

    /** Sets the user as onboarded and persists to store. */
    public void setOnboarded() {
        if (mIsOnboarded) {
            return;
        }
        Log.d(TAG, "Setting user as onboarded.");
        mIsOnboarded = true;
        mWifiConfigManager.saveToStore(false /* forceWrite */);
    }

    private NotificationManager getNotificationManager() {
        if (mNotificationManager == null) {
            mNotificationManager = (NotificationManager)
                    mContext.getSystemService(Context.NOTIFICATION_SERVICE);
        }
        return mNotificationManager;
    }

    /** Returns the {@link WakeupConfigStoreData.DataSource} for the onboarded status. */
    public WakeupConfigStoreData.DataSource<Boolean> getIsOnboadedDataSource() {
        return new IsOnboardedDataSource();
    }

    /** Returns the {@link WakeupConfigStoreData.DataSource} for the notification status. */
    public WakeupConfigStoreData.DataSource<Integer> getNotificationsDataSource() {
        return new NotificationsDataSource();
    }

    private class IsOnboardedDataSource implements WakeupConfigStoreData.DataSource<Boolean> {

        @Override
        public Boolean getData() {
            return mIsOnboarded;
        }

        @Override
        public void setData(Boolean data) {
            mIsOnboarded = data;
        }
    }

    private class NotificationsDataSource implements WakeupConfigStoreData.DataSource<Integer> {

        @Override
        public Integer getData() {
            return mTotalNotificationsShown;
        }

        @Override
        public void setData(Integer data) {
            mTotalNotificationsShown = data;
        }
    }
}
