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

import android.app.AlertDialog;
import android.app.Notification;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.wifi.WifiConfiguration;
import android.os.Handler;
import android.os.Process;
import android.util.Log;

import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.wifi.resources.R;

/**
 * This class may be used to launch notifications when wifi connections fail.
 */
public class ConnectionFailureNotifier {
    private static final String TAG = "ConnectionFailureNotifier";

    private final WifiContext mContext;
    private final FrameworkFacade mFrameworkFacade;
    private final WifiConfigManager mWifiConfigManager;
    private final WifiConnectivityManager mWifiConnectivityManager;
    private final WifiNotificationManager mNotificationManager;
    private final Handler mHandler;
    private final ConnectionFailureNotificationBuilder mConnectionFailureNotificationBuilder;

    public ConnectionFailureNotifier(
            WifiContext context,
            FrameworkFacade framework,
            WifiConfigManager wifiConfigManager,
            WifiConnectivityManager wifiConnectivityManager,
            Handler handler,
            WifiNotificationManager notificationManager,
            ConnectionFailureNotificationBuilder connectionFailureNotificationBuilder) {
        mContext = context;
        mFrameworkFacade = framework;
        mWifiConfigManager = wifiConfigManager;
        mWifiConnectivityManager = wifiConnectivityManager;
        mNotificationManager = notificationManager;
        mHandler = handler;
        mConnectionFailureNotificationBuilder = connectionFailureNotificationBuilder;

        IntentFilter filter = new IntentFilter();
        filter.addAction(ConnectionFailureNotificationBuilder
                .ACTION_SHOW_SET_RANDOMIZATION_DETAILS);
        mContext.registerReceiver(
                new BroadcastReceiver() {
                    @Override
                    public void onReceive(Context context, Intent intent) {
                        String action = intent.getAction();
                        if (action.equals(ConnectionFailureNotificationBuilder
                                .ACTION_SHOW_SET_RANDOMIZATION_DETAILS)) {
                            int networkId = intent.getIntExtra(
                                    ConnectionFailureNotificationBuilder
                                            .RANDOMIZATION_SETTINGS_NETWORK_ID,
                                    WifiConfiguration.INVALID_NETWORK_ID);
                            String ssidAndSecurityType = intent.getStringExtra(
                                    ConnectionFailureNotificationBuilder
                                            .RANDOMIZATION_SETTINGS_NETWORK_SSID);
                            showRandomizationSettingsDialog(networkId, ssidAndSecurityType);
                        }
                    }
                }, filter);
    }

    /**
     * Shows a notification which will bring up a dialog which offers the user an option to disable
     * MAC randomization on |networkdId|.
     * @param networkId
     */
    public void showFailedToConnectDueToNoRandomizedMacSupportNotification(int networkId) {
        WifiConfiguration config = mWifiConfigManager.getConfiguredNetwork(networkId);
        if (config == null) {
            return;
        }
        Notification notification = mConnectionFailureNotificationBuilder
                .buildNoMacRandomizationSupportNotification(config);
        mNotificationManager.notify(SystemMessage.NOTE_NETWORK_NO_MAC_RANDOMIZATION_SUPPORT,
                notification);
    }

    class DisableMacRandomizationListener implements DialogInterface.OnClickListener {
        private WifiConfiguration mConfig;

        DisableMacRandomizationListener(WifiConfiguration config) {
            mConfig = config;
        }

        @Override
        public void onClick(DialogInterface dialog, int which) {
            mHandler.post(() -> {
                mConfig.macRandomizationSetting =
                        WifiConfiguration.RANDOMIZATION_NONE;
                mWifiConfigManager.addOrUpdateNetwork(mConfig, Process.SYSTEM_UID);
                WifiConfiguration updatedConfig =
                        mWifiConfigManager.getConfiguredNetwork(mConfig.networkId);
                if (updatedConfig.macRandomizationSetting
                        == WifiConfiguration.RANDOMIZATION_NONE) {
                    String message = mContext.getResources().getString(
                            R.string.wifi_disable_mac_randomization_dialog_success);
                    mFrameworkFacade.showToast(mContext, message);
                    mWifiConfigManager.enableNetwork(updatedConfig.networkId, true,
                            Process.SYSTEM_UID, null);
                    mWifiConnectivityManager.forceConnectivityScan(
                            ClientModeImpl.WIFI_WORK_SOURCE);
                } else {
                    // Shouldn't ever fail, but here for completeness
                    String message = mContext.getResources().getString(
                            R.string.wifi_disable_mac_randomization_dialog_failure);
                    mFrameworkFacade.showToast(mContext, message);
                    Log.e(TAG, "Failed to modify mac randomization setting");
                }
            });
        }
    }

    /**
     * Class to show a AlertDialog which notifies the user of a network not being privacy
     * compliant and then suggests an action.
     */
    private void showRandomizationSettingsDialog(int networkId, String ssidAndSecurityType) {
        WifiConfiguration config = mWifiConfigManager.getConfiguredNetwork(networkId);
        // Make sure the networkId is still pointing to the correct WifiConfiguration since
        // there might be a large time gap between when the notification shows and when
        // it's tapped.
        if (config == null || ssidAndSecurityType == null
                || !ssidAndSecurityType.equals(config.getSsidAndSecurityTypeString())) {
            String message = mContext.getResources().getString(
                    R.string.wifi_disable_mac_randomization_dialog_network_not_found);
            mFrameworkFacade.showToast(mContext, message);
            return;
        }

        AlertDialog dialog = mConnectionFailureNotificationBuilder
                .buildChangeMacRandomizationSettingDialog(config.SSID,
                        new DisableMacRandomizationListener(config));
        dialog.show();
    }
}
