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

import android.app.Activity;
import android.app.settings.SettingsEnums;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.os.Build;
import android.os.UserHandle;
import android.os.UserManager;
import android.text.BidiFormatter;
import android.text.TextUtils;
import android.widget.Toast;

import androidx.preference.Preference;

import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.InstrumentedPreferenceFragment;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.password.ChooseLockSettingsHelper;
import com.android.settings.slices.Sliceable;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.development.DevelopmentSettingsEnabler;

public class BuildNumberPreferenceController extends BasePreferenceController implements
        LifecycleObserver, OnStart {

    static final int TAPS_TO_BE_A_DEVELOPER = 7;
    static final int REQUEST_CONFIRM_PASSWORD_FOR_DEV_PREF = 100;

    private Activity mActivity;
    private InstrumentedPreferenceFragment mFragment;
    private final UserManager mUm;
    private final MetricsFeatureProvider mMetricsFeatureProvider;

    private Toast mDevHitToast;
    private RestrictedLockUtils.EnforcedAdmin mDebuggingFeaturesDisallowedAdmin;
    private boolean mDebuggingFeaturesDisallowedBySystem;
    private int mDevHitCountdown;
    private boolean mProcessingLastDevHit;

    public BuildNumberPreferenceController(Context context, String key) {
        super(context, key);
        mUm = (UserManager) context.getSystemService(Context.USER_SERVICE);
        mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
    }

    public void setHost(InstrumentedPreferenceFragment fragment) {
        mFragment = fragment;
        mActivity = fragment.getActivity();
    }

    @Override
    public CharSequence getSummary() {
        return BidiFormatter.getInstance().unicodeWrap(Build.DISPLAY);
    }

    @Override
    public void onStart() {
        mDebuggingFeaturesDisallowedAdmin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
                mContext, UserManager.DISALLOW_DEBUGGING_FEATURES, UserHandle.myUserId());
        mDebuggingFeaturesDisallowedBySystem = RestrictedLockUtilsInternal.hasBaseUserRestriction(
                mContext, UserManager.DISALLOW_DEBUGGING_FEATURES, UserHandle.myUserId());
        mDevHitCountdown = DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(mContext)
                ? -1 : TAPS_TO_BE_A_DEVELOPER;
        mDevHitToast = null;
    }

    @Override
    public int getAvailabilityStatus() {
        return AVAILABLE;
    }

    @Override
    public boolean isSliceable() {
        return true;
    }

    @Override
    public boolean isCopyableSlice() {
        return true;
    }

    @Override
    public boolean useDynamicSliceSummary() {
        return true;
    }

    @Override
    public void copy() {
        Sliceable.setCopyContent(mContext, getSummary(), mContext.getText(R.string.build_number));
    }

    @Override
    public boolean handlePreferenceTreeClick(Preference preference) {
        if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) {
            return false;
        }
        if (Utils.isMonkeyRunning()) {
            return false;
        }
        // Don't enable developer options for secondary non-demo users.
        if (!(mUm.isAdminUser() || mUm.isDemoUser())) {
            mMetricsFeatureProvider.action(
                    mContext, SettingsEnums.ACTION_SETTINGS_BUILD_NUMBER_PREF);
            return false;
        }

        // Don't enable developer options until device has been provisioned
        if (!Utils.isDeviceProvisioned(mContext)) {
            mMetricsFeatureProvider.action(
                    mContext, SettingsEnums.ACTION_SETTINGS_BUILD_NUMBER_PREF);
            return false;
        }

        if (mUm.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES)) {
            if (mUm.isDemoUser()) {
                // Route to demo device owner to lift the debugging restriction.
                final ComponentName componentName = Utils.getDeviceOwnerComponent(mContext);
                if (componentName != null) {
                    final Intent requestDebugFeatures = new Intent()
                            .setPackage(componentName.getPackageName())
                            .setAction("com.android.settings.action.REQUEST_DEBUG_FEATURES");
                    final ResolveInfo resolveInfo = mContext.getPackageManager().resolveActivity(
                            requestDebugFeatures, 0);
                    if (resolveInfo != null) {
                        mContext.startActivity(requestDebugFeatures);
                        return false;
                    }
                }
            }
            if (mDebuggingFeaturesDisallowedAdmin != null &&
                    !mDebuggingFeaturesDisallowedBySystem) {
                RestrictedLockUtils.sendShowAdminSupportDetailsIntent(mContext,
                        mDebuggingFeaturesDisallowedAdmin);
            }
            mMetricsFeatureProvider.action(
                    mContext, SettingsEnums.ACTION_SETTINGS_BUILD_NUMBER_PREF);
            return false;
        }

        if (mDevHitCountdown > 0) {
            mDevHitCountdown--;
            if (mDevHitCountdown == 0 && !mProcessingLastDevHit) {
                // Add 1 count back, then start password confirmation flow.
                mDevHitCountdown++;
                final ChooseLockSettingsHelper helper =
                        new ChooseLockSettingsHelper(mActivity, mFragment);
                mProcessingLastDevHit = helper.launchConfirmationActivity(
                        REQUEST_CONFIRM_PASSWORD_FOR_DEV_PREF,
                        mContext.getString(R.string.unlock_set_unlock_launch_picker_title));
                if (!mProcessingLastDevHit) {
                    enableDevelopmentSettings();
                }
                mMetricsFeatureProvider.action(
                        mMetricsFeatureProvider.getAttribution(mActivity),
                        MetricsEvent.FIELD_SETTINGS_BUILD_NUMBER_DEVELOPER_MODE_ENABLED,
                        mFragment.getMetricsCategory(),
                        null,
                        mProcessingLastDevHit ? 0 : 1);
            } else if (mDevHitCountdown > 0
                    && mDevHitCountdown < (TAPS_TO_BE_A_DEVELOPER - 2)) {
                if (mDevHitToast != null) {
                    mDevHitToast.cancel();
                }
                mDevHitToast = Toast.makeText(mContext,
                        mContext.getResources().getQuantityString(
                                R.plurals.show_dev_countdown, mDevHitCountdown,
                                mDevHitCountdown),
                        Toast.LENGTH_SHORT);
                mDevHitToast.show();
            }

            mMetricsFeatureProvider.action(
                    mMetricsFeatureProvider.getAttribution(mActivity),
                    MetricsEvent.FIELD_SETTINGS_BUILD_NUMBER_DEVELOPER_MODE_ENABLED,
                    mFragment.getMetricsCategory(),
                    null,
                    0);
        } else if (mDevHitCountdown < 0) {
            if (mDevHitToast != null) {
                mDevHitToast.cancel();
            }
            mDevHitToast = Toast.makeText(mContext, R.string.show_dev_already,
                    Toast.LENGTH_LONG);
            mDevHitToast.show();
            mMetricsFeatureProvider.action(
                    mMetricsFeatureProvider.getAttribution(mActivity),
                    MetricsEvent.FIELD_SETTINGS_BUILD_NUMBER_DEVELOPER_MODE_ENABLED,
                    mFragment.getMetricsCategory(),
                    null,
                    1);
        }
        return true;
    }

    /**
     * Handles password confirmation result.
     *
     * @return if activity result is handled.
     */
    public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode != REQUEST_CONFIRM_PASSWORD_FOR_DEV_PREF) {
            return false;
        }
        if (resultCode == Activity.RESULT_OK) {
            enableDevelopmentSettings();
        }
        mProcessingLastDevHit = false;
        return true;
    }

    /**
     * Enables development settings. Only call this after confirming password.
     */
    private void enableDevelopmentSettings() {
        mDevHitCountdown = 0;
        mProcessingLastDevHit = false;
        DevelopmentSettingsEnabler.setDevelopmentSettingsEnabled(mContext, true);
        if (mDevHitToast != null) {
            mDevHitToast.cancel();
        }
        mDevHitToast = Toast.makeText(mContext, R.string.show_dev_on,
                Toast.LENGTH_LONG);
        mDevHitToast.show();
    }
}
