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

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.TetherUtil;
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() {
        return TetherUtil.isTetherAvailable(mContext);
    }

    @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();
        }

    }
}
