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

import android.app.Dialog;
import android.app.settings.SettingsEnums;
import android.content.DialogInterface;
import android.content.pm.PackageInfo;
import android.net.VpnManager;
import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserManager;

import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;

import com.android.internal.net.VpnConfig;
import com.android.settings.R;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;

/**
 * Fragment wrapper around an {@link AppDialog}.
 */
public class AppDialogFragment extends InstrumentedDialogFragment implements AppDialog.Listener {
    private static final String TAG_APP_DIALOG = "vpnappdialog";
    private static final String TAG = "AppDialogFragment";

    private static final String ARG_MANAGING = "managing";
    private static final String ARG_LABEL = "label";
    private static final String ARG_CONNECTED = "connected";
    private static final String ARG_PACKAGE = "package";

    private PackageInfo mPackageInfo;
    private Listener mListener;

    private UserManager mUserManager;
    private VpnManager mVpnManager;

    @Override
    public int getMetricsCategory() {
        return SettingsEnums.DIALOG_VPN_APP_CONFIG;
    }

    public interface Listener {
        void onForget();
        void onCancel();
    }

    public static void show(Fragment parent, PackageInfo packageInfo, String label,
            boolean managing, boolean connected) {
        if (!managing && !connected) {
            // We can't display anything useful for this case.
            return;
        }
        show(parent, null, packageInfo, label, managing, connected);
    }

    public static void show(Fragment parent, Listener listener, PackageInfo packageInfo,
            String label, boolean managing, boolean connected) {
        if (!parent.isAdded()) {
            return;
        }

        Bundle args = new Bundle();
        args.putParcelable(ARG_PACKAGE, packageInfo);
        args.putString(ARG_LABEL, label);
        args.putBoolean(ARG_MANAGING, managing);
        args.putBoolean(ARG_CONNECTED, connected);

        final AppDialogFragment frag = new AppDialogFragment();
        frag.mListener = listener;
        frag.setArguments(args);
        frag.setTargetFragment(parent, 0);
        frag.show(parent.getFragmentManager(), TAG_APP_DIALOG);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mUserManager = UserManager.get(getContext());
        mVpnManager = getContext().getSystemService(VpnManager.class);
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Bundle args = getArguments();
        final String label = args.getString(ARG_LABEL);
        boolean managing = args.getBoolean(ARG_MANAGING);
        boolean connected = args.getBoolean(ARG_CONNECTED);
        mPackageInfo = args.getParcelable(ARG_PACKAGE);

        if (managing) {
            return new AppDialog(getActivity(), this, mPackageInfo, label);
        } else {
            // Build an AlertDialog with an option to disconnect.
            AlertDialog.Builder dlog = new AlertDialog.Builder(getActivity())
                    .setTitle(label)
                    .setMessage(getActivity().getString(R.string.vpn_disconnect_confirm))
                    .setNegativeButton(getActivity().getString(R.string.vpn_cancel), null);

            if (connected && !isUiRestricted()) {
                dlog.setPositiveButton(getActivity().getString(R.string.vpn_disconnect),
                        new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                onDisconnect(dialog);
                            }
                        });
            }
            return dlog.create();
        }
    }

    @Override
    public void onCancel(DialogInterface dialog) {
        dismiss();
        if (mListener != null) {
            mListener.onCancel();
        }
        super.onCancel(dialog);
    }

    @Override
    public void onForget(final DialogInterface dialog) {
        if (isUiRestricted()) {
            return;
        }
        final int userId = getUserId();
        mVpnManager.setVpnPackageAuthorization(
                mPackageInfo.packageName, userId, VpnManager.TYPE_VPN_NONE);
        onDisconnect(dialog);

        if (mListener != null) {
            mListener.onForget();
        }
    }

    private void onDisconnect(final DialogInterface dialog) {
        if (isUiRestricted()) {
            return;
        }
        final int userId = getUserId();
        if (mPackageInfo.packageName.equals(VpnUtils.getConnectedPackage(mVpnManager, userId))) {
            mVpnManager.setAlwaysOnVpnPackageForUser(userId, null, /* lockdownEnabled */ false,
                    /* lockdownAllowlist */ null);
            mVpnManager.prepareVpn(mPackageInfo.packageName, VpnConfig.LEGACY_VPN, userId);
        }
    }

    private boolean isUiRestricted() {
        final UserHandle userHandle = UserHandle.of(getUserId());
        return mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_VPN, userHandle);
    }

    private int getUserId() {
        return UserHandle.getUserId(mPackageInfo.applicationInfo.uid);
    }
}
