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

import static android.os.UserManager.DISALLOW_CONFIG_TETHERING;
import static com.android.settingslib.RestrictedLockUtils.checkIfRestrictionEnforced;
import static com.android.settingslib.RestrictedLockUtils.hasBaseUserRestriction;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothPan;
import android.bluetooth.BluetoothProfile;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.ContentObserver;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.UserHandle;
import android.provider.Settings;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;

import com.android.settings.R;
import com.android.settings.TetherSettings;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnCreate;
import com.android.settingslib.core.lifecycle.events.OnDestroy;
import com.android.settingslib.core.lifecycle.events.OnPause;
import com.android.settingslib.core.lifecycle.events.OnResume;

import java.util.concurrent.atomic.AtomicReference;

public class TetherPreferenceController extends AbstractPreferenceController implements
        PreferenceControllerMixin, LifecycleObserver, OnCreate, OnResume, OnPause, OnDestroy {

    private static final String KEY_TETHER_SETTINGS = "tether_settings";

    private final boolean mAdminDisallowedTetherConfig;
    private final AtomicReference<BluetoothPan> mBluetoothPan;
    private final ConnectivityManager mConnectivityManager;
    private final BluetoothAdapter mBluetoothAdapter;
    @VisibleForTesting
    final BluetoothProfile.ServiceListener mBtProfileServiceListener =
            new android.bluetooth.BluetoothProfile.ServiceListener() {
                public void onServiceConnected(int profile, BluetoothProfile proxy) {
                    mBluetoothPan.set((BluetoothPan) proxy);
                    updateSummary();
                }

                public void onServiceDisconnected(int profile) {
                    mBluetoothPan.set(null);
                }
            };

    private SettingObserver mAirplaneModeObserver;
    private Preference mPreference;
    private TetherBroadcastReceiver mTetherReceiver;

    @VisibleForTesting(otherwise = VisibleForTesting.NONE)
    TetherPreferenceController() {
        super(null);
        mAdminDisallowedTetherConfig = false;
        mBluetoothPan = new AtomicReference<>();
        mConnectivityManager = null;
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    }

    public TetherPreferenceController(Context context, Lifecycle lifecycle) {
        super(context);
        mBluetoothPan = new AtomicReference<>();
        mAdminDisallowedTetherConfig = isTetherConfigDisallowed(context);
        mConnectivityManager =
                (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (lifecycle != null) {
            lifecycle.addObserver(this);
        }
    }

    @Override
    public void displayPreference(PreferenceScreen screen) {
        super.displayPreference(screen);
        mPreference = screen.findPreference(KEY_TETHER_SETTINGS);
        if (mPreference != null && !mAdminDisallowedTetherConfig) {
            mPreference.setTitle(
                    com.android.settingslib.Utils.getTetheringLabel(mConnectivityManager));

            // Grey out if provisioning is not available.
            mPreference.setEnabled(!TetherSettings.isProvisioningNeededButUnavailable(mContext));
        }
    }

    @Override
    public boolean isAvailable() {
        final boolean isBlocked =
                (!mConnectivityManager.isTetheringSupported() && !mAdminDisallowedTetherConfig)
                        || hasBaseUserRestriction(mContext, DISALLOW_CONFIG_TETHERING,
                        UserHandle.myUserId());
        return !isBlocked;
    }

    @Override
    public void updateState(Preference preference) {
        updateSummary();
    }

    @Override
    public String getPreferenceKey() {
        return KEY_TETHER_SETTINGS;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        if (mBluetoothAdapter != null &&
            mBluetoothAdapter.getState() == BluetoothAdapter.STATE_ON) {
            mBluetoothAdapter.getProfileProxy(mContext, mBtProfileServiceListener,
                    BluetoothProfile.PAN);
        }
    }

    @Override
    public void onResume() {
        if (mAirplaneModeObserver == null) {
            mAirplaneModeObserver = new SettingObserver();
        }
        if (mTetherReceiver == null) {
            mTetherReceiver = new TetherBroadcastReceiver();
        }
        mContext.registerReceiver(
                mTetherReceiver, new IntentFilter(ConnectivityManager.ACTION_TETHER_STATE_CHANGED));
        mContext.getContentResolver()
                .registerContentObserver(mAirplaneModeObserver.uri, false, mAirplaneModeObserver);
    }

    @Override
    public void onPause() {
        if (mAirplaneModeObserver != null) {
            mContext.getContentResolver().unregisterContentObserver(mAirplaneModeObserver);
        }
        if (mTetherReceiver != null) {
            mContext.unregisterReceiver(mTetherReceiver);
        }
    }

    @Override
    public void onDestroy() {
        final BluetoothProfile profile = mBluetoothPan.getAndSet(null);
        if (profile != null && mBluetoothAdapter != null) {
            mBluetoothAdapter.closeProfileProxy(BluetoothProfile.PAN, profile);
        }
    }

    public static boolean isTetherConfigDisallowed(Context context) {
        return checkIfRestrictionEnforced(
                context, DISALLOW_CONFIG_TETHERING, UserHandle.myUserId()) != null;
    }

    @VisibleForTesting
    void updateSummary() {
        if (mPreference == null) {
            // Preference is not ready yet.
            return;
        }
        String[] allTethered = mConnectivityManager.getTetheredIfaces();
        String[] wifiTetherRegex = mConnectivityManager.getTetherableWifiRegexs();
        String[] bluetoothRegex = mConnectivityManager.getTetherableBluetoothRegexs();

        boolean hotSpotOn = false;
        boolean tetherOn = false;
        if (allTethered != null) {
            if (wifiTetherRegex != null) {
                for (String tethered : allTethered) {
                    for (String regex : wifiTetherRegex) {
                        if (tethered.matches(regex)) {
                            hotSpotOn = true;
                            break;
                        }
                    }
                }
            }
            if (allTethered.length > 1) {
                // We have more than 1 tethered connection
                tetherOn = true;
            } else if (allTethered.length == 1) {
                // We have more than 1 tethered, it's either wifiTether (hotspot), or other type of
                // tether.
                tetherOn = !hotSpotOn;
            } else {
                // No tethered connection.
                tetherOn = false;
            }
        }
        if (!tetherOn
                && bluetoothRegex != null && bluetoothRegex.length > 0
                && mBluetoothAdapter != null
                && mBluetoothAdapter.getState() == BluetoothAdapter.STATE_ON) {
            // Check bluetooth state. It's not included in mConnectivityManager.getTetheredIfaces.
            final BluetoothPan pan = mBluetoothPan.get();
            tetherOn = pan != null && pan.isTetheringOn();
        }
        if (!hotSpotOn && !tetherOn) {
            // Both off
            mPreference.setSummary(R.string.switch_off_text);
        } else if (hotSpotOn && tetherOn) {
            // Both on
            mPreference.setSummary(R.string.tether_settings_summary_hotspot_on_tether_on);
        } else if (hotSpotOn) {
            mPreference.setSummary(R.string.tether_settings_summary_hotspot_on_tether_off);
        } else {
            mPreference.setSummary(R.string.tether_settings_summary_hotspot_off_tether_on);
        }
    }

    private void updateSummaryToOff() {
        if (mPreference == null) {
            // Preference is not ready yet.
            return;
        }
        mPreference.setSummary(R.string.switch_off_text);
    }

    class SettingObserver extends ContentObserver {

        public final Uri uri;

        public SettingObserver() {
            super(new Handler());
            uri = Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON);
        }

        @Override
        public void onChange(boolean selfChange, Uri uri) {
            super.onChange(selfChange, uri);
            if (this.uri.equals(uri)) {
                boolean isAirplaneMode = Settings.Global.getInt(mContext.getContentResolver(),
                        Settings.Global.AIRPLANE_MODE_ON, 0) != 0;
                if (isAirplaneMode) {
                    // Airplane mode is on. Update summary to say tether is OFF directly. We cannot
                    // go through updateSummary() because turning off tether takes time, and we
                    // might still get "ON" status when rerun updateSummary(). So, just say it's off
                    updateSummaryToOff();
                }
            }
        }
    }

    @VisibleForTesting
    class TetherBroadcastReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            updateSummary();
        }

    }
}
