/*
 * Copyright (C) 2015 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.tv.settings.about;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ResolveInfo;
import android.os.Build;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.os.SELinux;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserManager;
import android.sysprop.TelephonyProperties;
import android.telephony.CarrierConfigManager;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
import android.widget.Toast;

import androidx.annotation.Keep;
import androidx.annotation.Nullable;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;

import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settingslib.DeviceInfoUtils;
import com.android.settingslib.Utils;
import com.android.settingslib.development.DevelopmentSettingsEnabler;
import com.android.tv.settings.MainFragment;
import com.android.tv.settings.PreferenceUtils;
import com.android.tv.settings.R;
import com.android.tv.settings.SettingsPreferenceFragment;
import com.android.tv.settings.name.DeviceManager;

import java.util.stream.Collectors;

/**
 * The "About" screen in TV settings.
 */
@Keep
public class AboutFragment extends SettingsPreferenceFragment {
    private static final String TAG = "AboutFragment";

    private static final String KEY_MANUAL = "manual";
    private static final String KEY_REGULATORY_INFO = "regulatory_info";
    private static final String KEY_SYSTEM_UPDATE_SETTINGS = "system_update_settings";
    private static final String PROPERTY_URL_SAFETYLEGAL = "ro.url.safetylegal";
    private static final String PROPERTY_SELINUX_STATUS = "ro.build.selinux";
    private static final String KEY_KERNEL_VERSION = "kernel_version";
    private static final String KEY_BUILD_NUMBER = "build_number";
    private static final String KEY_DEVICE_MODEL = "device_model";
    private static final String KEY_SELINUX_STATUS = "selinux_status";
    private static final String KEY_BASEBAND_VERSION = "baseband_version";
    private static final String KEY_FIRMWARE_VERSION = "firmware_version";
    private static final String KEY_SECURITY_PATCH = "security_patch";
    private static final String KEY_UPDATE_SETTING = "additional_system_update_settings";
    private static final String KEY_EQUIPMENT_ID = "fcc_equipment_id";
    private static final String PROPERTY_EQUIPMENT_ID = "ro.ril.fccid";
    private static final String KEY_DEVICE_FEEDBACK = "device_feedback";
    private static final String KEY_SAFETY_LEGAL = "safetylegal";
    private static final String KEY_DEVICE_NAME = "device_name";
    private static final String KEY_TUTORIALS = "tutorials";

    static final int TAPS_TO_BE_A_DEVELOPER = 7;

    long[] mHits = new long[3];
    int mDevHitCountdown;
    Toast mDevHitToast;

    private UserManager mUm;

    private final BroadcastReceiver mDeviceNameReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            refreshDeviceName();
        }
    };

    public static AboutFragment newInstance() {
        return new AboutFragment();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        mUm = UserManager.get(getActivity());

        super.onCreate(savedInstanceState);
    }

    @Override
    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
        setPreferencesFromResource(R.xml.device_info_settings, null);
        final PreferenceScreen screen = getPreferenceScreen();

        refreshDeviceName();
        final Preference deviceNamePref = findPreference(KEY_DEVICE_NAME);
        PreferenceUtils.resolveSystemActivityOrRemove(getActivity(), screen, deviceNamePref, 0);

        final Preference firmwareVersionPref = findPreference(KEY_FIRMWARE_VERSION);
        firmwareVersionPref.setSummary(Build.VERSION.RELEASE_OR_CODENAME);
        firmwareVersionPref.setEnabled(true);

        final Preference securityPatchPref = findPreference(KEY_SECURITY_PATCH);
        final String patch = DeviceInfoUtils.getSecurityPatch();
        if (!TextUtils.isEmpty(patch)) {
            securityPatchPref.setSummary(patch);
        } else {
            removePreference(securityPatchPref);
        }

        String basebandVersion = TelephonyProperties.baseband_version().stream()
                .map(x -> x == null ? "" : x)
                .collect(Collectors.joining(","));

        if (basebandVersion.isEmpty()) {
            basebandVersion = getResources().getString(R.string.device_info_default);
        }

        findPreference(KEY_BASEBAND_VERSION).setSummary(basebandVersion);
        findPreference(KEY_DEVICE_MODEL).setSummary(Build.MODEL + DeviceInfoUtils.getMsvSuffix());
        findPreference(KEY_EQUIPMENT_ID)
                .setSummary(getSystemPropertySummary(PROPERTY_EQUIPMENT_ID));

        final Preference buildNumberPref = findPreference(KEY_BUILD_NUMBER);
        buildNumberPref.setSummary(Build.DISPLAY);
        buildNumberPref.setEnabled(true);
        findPreference(KEY_KERNEL_VERSION)
                .setSummary(DeviceInfoUtils.getFormattedKernelVersion(getContext()));

        final Preference selinuxPref = findPreference(KEY_SELINUX_STATUS);
        if (!SELinux.isSELinuxEnabled()) {
            selinuxPref.setSummary(R.string.selinux_status_disabled);
        } else if (!SELinux.isSELinuxEnforced()) {
            selinuxPref.setSummary(R.string.selinux_status_permissive);
        }

        // Remove selinux information if property is not present
        if (TextUtils.isEmpty(SystemProperties.get(PROPERTY_SELINUX_STATUS))) {
            removePreference(selinuxPref);
        }

        // Remove Safety information preference if PROPERTY_URL_SAFETYLEGAL is not set
        if (TextUtils.isEmpty(SystemProperties.get(PROPERTY_URL_SAFETYLEGAL))) {
            removePreference(findPreference(KEY_SAFETY_LEGAL));
        }

        // Remove Equipment id preference if FCC ID is not set by RIL
        if (TextUtils.isEmpty(SystemProperties.get(PROPERTY_EQUIPMENT_ID))) {
            removePreference(findPreference(KEY_EQUIPMENT_ID));
        }

        // Remove Baseband version if wifi-only device
        if (Utils.isWifiOnly(getActivity())) {
            removePreference(findPreference(KEY_BASEBAND_VERSION));
        }

        // Dont show feedback option if there is no reporter.
        if (TextUtils.isEmpty(DeviceInfoUtils.getFeedbackReporterPackage(getActivity()))) {
            removePreference(findPreference(KEY_DEVICE_FEEDBACK));
        }

        final Preference updateSettingsPref = findPreference(KEY_SYSTEM_UPDATE_SETTINGS);
        if (mUm.isAdminUser()) {
            PreferenceUtils.resolveSystemActivityOrRemove(getActivity(), screen,
                    updateSettingsPref, PreferenceUtils.FLAG_SET_TITLE);
        } else if (updateSettingsPref != null) {
            // Remove for secondary users
            removePreference(updateSettingsPref);
        }

        // Read platform settings for additional system update setting
        if (!getResources().getBoolean(R.bool.config_additional_system_update_setting_enable)) {
            removePreference(findPreference(KEY_UPDATE_SETTING));
        }

        // Remove manual entry if none present.
        if (!getResources().getBoolean(R.bool.config_show_manual)) {
            removePreference(findPreference(KEY_MANUAL));
        }

        // Remove regulatory information if none present.
        final Preference regulatoryPref = findPreference(KEY_REGULATORY_INFO);
        PreferenceUtils.resolveSystemActivityOrRemove(getActivity(), screen, regulatoryPref, 0);
    }

    private void removePreference(@Nullable Preference preference) {
        if (preference != null) {
            getPreferenceScreen().removePreference(preference);
        }
    }

    @Override
    public void onStart() {
        super.onStart();
        refreshDeviceName();

        LocalBroadcastManager.getInstance(getContext()).registerReceiver(mDeviceNameReceiver,
                new IntentFilter(DeviceManager.ACTION_DEVICE_NAME_UPDATE));
    }

    @Override
    public void onResume() {
        super.onResume();
        mDevHitCountdown = DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(getContext())
                ? -1 : TAPS_TO_BE_A_DEVELOPER;
        mDevHitToast = null;
        updateTutorials();
    }

    @Override
    public void onStop() {
        super.onStop();
        LocalBroadcastManager.getInstance(getContext()).unregisterReceiver(mDeviceNameReceiver);
    }

    private void refreshDeviceName() {
        final Preference deviceNamePref = findPreference(KEY_DEVICE_NAME);
        if (deviceNamePref != null) {
            deviceNamePref.setSummary(DeviceManager.getDeviceName(getActivity()));
        }
    }

    @Override
    public boolean onPreferenceTreeClick(Preference preference) {
        switch (preference.getKey()) {
            case KEY_FIRMWARE_VERSION:
                System.arraycopy(mHits, 1, mHits, 0, mHits.length - 1);
                mHits[mHits.length - 1] = SystemClock.uptimeMillis();
                if (mHits[0] >= (SystemClock.uptimeMillis() - 500)) {
                    if (mUm.hasUserRestriction(UserManager.DISALLOW_FUN)) {
                        Log.d(TAG, "Sorry, no fun for you!");
                        return false;
                    }

                    Intent intent = new Intent(Intent.ACTION_MAIN);
                    intent.setClassName("android",
                            com.android.internal.app.PlatLogoActivity.class.getName());
                    try {
                        startActivity(intent);
                    } catch (Exception e) {
                        Log.e(TAG, "Unable to start activity " + intent.toString());
                    }
                }
                break;
            case KEY_BUILD_NUMBER:
                // Don't enable developer options for secondary users.
                if (!mUm.isAdminUser()) {
                    mMetricsFeatureProvider.action(getContext(),
                            MetricsEvent.ACTION_SETTINGS_BUILD_NUMBER_PREF);
                    return true;
                }

                if (mUm.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES)) {
                    mMetricsFeatureProvider.action(getContext(),
                            MetricsEvent.ACTION_SETTINGS_BUILD_NUMBER_PREF);
                    return true;
                }

                if (mDevHitCountdown > 0) {
                    mDevHitCountdown--;
                    if (mDevHitCountdown == 0) {
                        DevelopmentSettingsEnabler
                                .setDevelopmentSettingsEnabled(getContext(), true);
                        if (mDevHitToast != null) {
                            mDevHitToast.cancel();
                        }
                        mDevHitToast = Toast.makeText(getActivity(), R.string.show_dev_on,
                                Toast.LENGTH_LONG);
                        mDevHitToast.show();
                        // This is good time to index the Developer Options
//                    Index.getInstance(
//                            getActivity().getApplicationContext()).updateFromClassNameResource(
//                            DevelopmentSettings.class.getName(), true, true);
                        mMetricsFeatureProvider.action(
                                getContext(), MetricsEvent.ACTION_SETTINGS_BUILD_NUMBER_PREF,
                                Pair.create(MetricsEvent
                                        .FIELD_SETTINGS_BUILD_NUMBER_DEVELOPER_MODE_ENABLED,
                                0));
                    } else if (mDevHitCountdown > 0
                            && mDevHitCountdown < (TAPS_TO_BE_A_DEVELOPER - 2)) {
                        if (mDevHitToast != null) {
                            mDevHitToast.cancel();
                        }
                        mDevHitToast = Toast
                                .makeText(getActivity(), getResources().getQuantityString(
                                        R.plurals.show_dev_countdown, mDevHitCountdown,
                                        mDevHitCountdown),
                                        Toast.LENGTH_SHORT);
                        mDevHitToast.show();
                    }
                    mMetricsFeatureProvider.action(
                            getContext(), MetricsEvent.ACTION_SETTINGS_BUILD_NUMBER_PREF,
                            Pair.create(
                                    MetricsEvent.FIELD_SETTINGS_BUILD_NUMBER_DEVELOPER_MODE_ENABLED,
                            0));
                } else if (mDevHitCountdown < 0) {
                    if (mDevHitToast != null) {
                        mDevHitToast.cancel();
                    }
                    mDevHitToast = Toast.makeText(getActivity(), R.string.show_dev_already,
                            Toast.LENGTH_LONG);
                    mDevHitToast.show();
                    mMetricsFeatureProvider.action(
                            getContext(), MetricsEvent.ACTION_SETTINGS_BUILD_NUMBER_PREF,
                            Pair.create(
                                    MetricsEvent.FIELD_SETTINGS_BUILD_NUMBER_DEVELOPER_MODE_ENABLED,
                            1));
                }
                break;
            case KEY_DEVICE_FEEDBACK:
                sendFeedback();
                break;
            case KEY_SYSTEM_UPDATE_SETTINGS:
                CarrierConfigManager configManager = (CarrierConfigManager)
                        getActivity().getSystemService(Context.CARRIER_CONFIG_SERVICE);
                PersistableBundle b = configManager.getConfig();
                if (b != null &&
                        b.getBoolean(CarrierConfigManager.KEY_CI_ACTION_ON_SYS_UPDATE_BOOL)) {
                    ciActionOnSysUpdate(b);
                }
                break;
        }
        return super.onPreferenceTreeClick(preference);
    }

    /**
     * Trigger client initiated action (send intent) on system update
     */
    private void ciActionOnSysUpdate(PersistableBundle b) {
        String intentStr = b.getString(CarrierConfigManager.
                KEY_CI_ACTION_ON_SYS_UPDATE_INTENT_STRING);
        if (!TextUtils.isEmpty(intentStr)) {
            String extra = b.getString(CarrierConfigManager.
                    KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_STRING);
            String extraVal = b.getString(CarrierConfigManager.
                    KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_VAL_STRING);

            Intent intent = new Intent(intentStr);
            if (!TextUtils.isEmpty(extra)) {
                intent.putExtra(extra, extraVal);
            }
            Log.d(TAG, "ciActionOnSysUpdate: broadcasting intent " + intentStr +
                    " with extra " + extra + ", " + extraVal);
            getActivity().getApplicationContext().sendBroadcast(intent);
        }
    }

    private String getSystemPropertySummary(String property) {
        return SystemProperties.get(property,
                getResources().getString(R.string.device_info_default));
    }

    private void sendFeedback() {
        String reporterPackage = DeviceInfoUtils.getFeedbackReporterPackage(getActivity());
        if (TextUtils.isEmpty(reporterPackage)) {
            return;
        }
        Intent intent = new Intent(Intent.ACTION_BUG_REPORT);
        intent.setPackage(reporterPackage);
        startActivityForResult(intent, 0);
    }

    private void updateTutorials() {
        final Preference deviceTutorialsPref = findPreference(KEY_TUTORIALS);
        if (deviceTutorialsPref != null) {
            final ResolveInfo info = MainFragment.systemIntentIsHandled(getContext(),
                    deviceTutorialsPref.getIntent());
            deviceTutorialsPref.setVisible(info != null);
            if (info != null) {
                deviceTutorialsPref.setTitle(info.loadLabel(getContext().getPackageManager()));
            }
        }
    }

    @Override
    public int getMetricsCategory() {
        return MetricsEvent.DEVICEINFO;
    }
}
