/*
 * Copyright (C) 2010 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.email.activity.setup;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.FragmentManager;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.util.Log;

import com.android.email.Email;
import com.android.email.R;
import com.android.email.SecurityPolicy;
import com.android.email.activity.ActivityHelper;
import com.android.emailcommon.provider.Account;
import com.android.emailcommon.provider.HostAuth;
import com.android.emailcommon.utility.Utility;

/**
 * Psuedo-activity (no UI) to bootstrap the user up to a higher desired security level.  This
 * bootstrap requires the following steps.
 *
 * 1.  Confirm the account of interest has any security policies defined - exit early if not
 * 2.  If not actively administrating the device, ask Device Policy Manager to start that
 * 3.  When we are actively administrating, check current policies and see if they're sufficient
 * 4.  If not, set policies
 * 5.  If necessary, request for user to update device password
 * 6.  If necessary, request for user to activate device encryption
 */
public class AccountSecurity extends Activity {
    private static final String TAG = "Email/AccountSecurity";

    private static final String EXTRA_ACCOUNT_ID = "ACCOUNT_ID";
    private static final String EXTRA_SHOW_DIALOG = "SHOW_DIALOG";
    private static final String EXTRA_PASSWORD_EXPIRING = "EXPIRING";
    private static final String EXTRA_PASSWORD_EXPIRED = "EXPIRED";

    private static final int REQUEST_ENABLE = 1;
    private static final int REQUEST_PASSWORD = 2;
    private static final int REQUEST_ENCRYPTION = 3;

    private boolean mTriedAddAdministrator = false;
    private boolean mTriedSetPassword = false;
    private boolean mTriedSetEncryption = false;
    private Account mAccount;

    /**
     * Used for generating intent for this activity (which is intended to be launched
     * from a notification.)
     *
     * @param context Calling context for building the intent
     * @param accountId The account of interest
     * @param showDialog If true, a simple warning dialog will be shown before kicking off
     * the necessary system settings.  Should be true anywhere the context of the security settings
     * is not clear (e.g. any time after the account has been set up).
     * @return an Intent which can be used to view that account
     */
    public static Intent actionUpdateSecurityIntent(Context context, long accountId,
            boolean showDialog) {
        Intent intent = new Intent(context, AccountSecurity.class);
        intent.putExtra(EXTRA_ACCOUNT_ID, accountId);
        intent.putExtra(EXTRA_SHOW_DIALOG, showDialog);
        return intent;
    }

    /**
     * Used for generating intent for this activity (which is intended to be launched
     * from a notification.)  This is a special mode of this activity which exists only
     * to give the user a dialog (for context) about a device pin/password expiration event.
     */
    public static Intent actionDevicePasswordExpirationIntent(Context context, long accountId,
            boolean expired) {
        Intent intent = new Intent(context, AccountSecurity.class);
        intent.putExtra(EXTRA_ACCOUNT_ID, accountId);
        intent.putExtra(expired ? EXTRA_PASSWORD_EXPIRED : EXTRA_PASSWORD_EXPIRING, true);
        return intent;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityHelper.debugSetWindowFlags(this);

        Intent i = getIntent();
        final long accountId = i.getLongExtra(EXTRA_ACCOUNT_ID, -1);
        final boolean showDialog = i.getBooleanExtra(EXTRA_SHOW_DIALOG, false);
        final boolean passwordExpiring = i.getBooleanExtra(EXTRA_PASSWORD_EXPIRING, false);
        final boolean passwordExpired = i.getBooleanExtra(EXTRA_PASSWORD_EXPIRED, false);
        SecurityPolicy security = SecurityPolicy.getInstance(this);
        security.clearNotification();
        if (accountId == -1) {
            finish();
            return;
        }

        mAccount = Account.restoreAccountWithId(AccountSecurity.this, accountId);
        if (mAccount == null) {
            finish();
            return;
        }

        // Special handling for password expiration events
        if (passwordExpiring || passwordExpired) {
            FragmentManager fm = getFragmentManager();
            if (fm.findFragmentByTag("password_expiration") == null) {
                PasswordExpirationDialog dialog =
                    PasswordExpirationDialog.newInstance(mAccount.getDisplayName(),
                            passwordExpired);
                dialog.show(fm, "password_expiration");
            }
            return;
        }
        // Otherwise, handle normal security settings flow
        if (mAccount.mPolicyKey != 0) {
            // This account wants to control security
            if (showDialog) {
                // Show dialog first, unless already showing (e.g. after rotation)
                FragmentManager fm = getFragmentManager();
                if (fm.findFragmentByTag("security_needed") == null) {
                    SecurityNeededDialog dialog =
                        SecurityNeededDialog.newInstance(mAccount.getDisplayName());
                    dialog.show(fm, "security_needed");
                }
            } else {
                // Go directly to security settings
                tryAdvanceSecurity(mAccount);
            }
            return;
        }
        finish();
    }

    /**
     * After any of the activities return, try to advance to the "next step"
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        tryAdvanceSecurity(mAccount);
        super.onActivityResult(requestCode, resultCode, data);
    }

    /**
     * Walk the user through the required steps to become an active administrator and with
     * the requisite security settings for the given account.
     *
     * These steps will be repeated each time we return from a given attempt (e.g. asking the
     * user to choose a device pin/password).  In a typical activation, we may repeat these
     * steps a few times.  It may go as far as step 5 (password) or step 6 (encryption), but it
     * will terminate when step 2 (isActive()) succeeds.
     *
     * If at any point we do not advance beyond a given user step, (e.g. the user cancels
     * instead of setting a password) we simply repost the security notification, and exit.
     * We never want to loop here.
     */
    private void tryAdvanceSecurity(Account account) {
        SecurityPolicy security = SecurityPolicy.getInstance(this);
        // Step 1.  Check if we are an active device administrator, and stop here to activate
        if (!security.isActiveAdmin()) {
            if (mTriedAddAdministrator) {
                if (Email.DEBUG) {
                    Log.d(TAG, "Not active admin: repost notification");
                }
                repostNotification(account, security);
                finish();
            } else {
                mTriedAddAdministrator = true;
                // retrieve name of server for the format string
                HostAuth hostAuth = HostAuth.restoreHostAuthWithId(this, account.mHostAuthKeyRecv);
                if (hostAuth == null) {
                    if (Email.DEBUG) {
                        Log.d(TAG, "No HostAuth: repost notification");
                    }
                    repostNotification(account, security);
                    finish();
                } else {
                    if (Email.DEBUG) {
                        Log.d(TAG, "Not active admin: post initial notification");
                    }
                    // try to become active - must happen here in activity, to get result
                    Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
                    intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
                            security.getAdminComponent());
                    intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,
                            this.getString(R.string.account_security_policy_explanation_fmt,
                                    hostAuth.mAddress));
                    startActivityForResult(intent, REQUEST_ENABLE);
                }
            }
            return;
        }

        // Step 2.  Check if the current aggregate security policy is being satisfied by the
        // DevicePolicyManager (the current system security level).
        if (security.isActive(null)) {
            if (Email.DEBUG) {
                Log.d(TAG, "Security active; clear holds");
            }
            Account.clearSecurityHoldOnAllAccounts(this);
            security.clearNotification();
            finish();
            return;
        }

        // Step 3.  Try to assert the current aggregate security requirements with the system.
        security.setActivePolicies();

        // Step 4.  Recheck the security policy, and determine what changes are needed (if any)
        // to satisfy the requirements.
        int inactiveReasons = security.getInactiveReasons(null);

        // Step 5.  If password is needed, try to have the user set it
        if ((inactiveReasons & SecurityPolicy.INACTIVE_NEED_PASSWORD) != 0) {
            if (mTriedSetPassword) {
                if (Email.DEBUG) {
                    Log.d(TAG, "Password needed; repost notification");
                }
                repostNotification(account, security);
                finish();
            } else {
                if (Email.DEBUG) {
                    Log.d(TAG, "Password needed; request it via DPM");
                }
                mTriedSetPassword = true;
                // launch the activity to have the user set a new password.
                Intent intent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
                startActivityForResult(intent, REQUEST_PASSWORD);
            }
            return;
        }

        // Step 6.  If encryption is needed, try to have the user set it
        if ((inactiveReasons & SecurityPolicy.INACTIVE_NEED_ENCRYPTION) != 0) {
            if (mTriedSetEncryption) {
                if (Email.DEBUG) {
                    Log.d(TAG, "Encryption needed; repost notification");
                }
                repostNotification(account, security);
                finish();
            } else {
                if (Email.DEBUG) {
                    Log.d(TAG, "Encryption needed; request it via DPM");
                }
                mTriedSetEncryption = true;
                // launch the activity to start up encryption.
                Intent intent = new Intent(DevicePolicyManager.ACTION_START_ENCRYPTION);
                startActivityForResult(intent, REQUEST_ENCRYPTION);
            }
            return;
        }

        // Step 7.  No problems were found, so clear holds and exit
        if (Email.DEBUG) {
            Log.d(TAG, "Policies enforced; clear holds");
        }
        Account.clearSecurityHoldOnAllAccounts(this);
        security.clearNotification();
        finish();
    }

    /**
     * Mark an account as not-ready-for-sync and post a notification to bring the user back here
     * eventually.
     */
    private void repostNotification(final Account account, final SecurityPolicy security) {
        if (account == null) return;
        Utility.runAsync(new Runnable() {
            @Override
            public void run() {
                security.policiesRequired(account.mId);
            }
        });
    }

    /**
     * Dialog briefly shown in some cases, to indicate the user that a security update is needed.
     * If the user clicks OK, we proceed into the "tryAdvanceSecurity" flow.  If the user cancels,
     * we repost the notification and finish() the activity.
     */
    public static class SecurityNeededDialog extends DialogFragment
            implements DialogInterface.OnClickListener {
        private static final String BUNDLE_KEY_ACCOUNT_NAME = "account_name";

        /**
         * Create a new dialog.
         */
        public static SecurityNeededDialog newInstance(String accountName) {
            final SecurityNeededDialog dialog = new SecurityNeededDialog();
            Bundle b = new Bundle();
            b.putString(BUNDLE_KEY_ACCOUNT_NAME, accountName);
            dialog.setArguments(b);
            return dialog;
        }

        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            final String accountName = getArguments().getString(BUNDLE_KEY_ACCOUNT_NAME);

            final Context context = getActivity();
            final Resources res = context.getResources();
            final AlertDialog.Builder b = new AlertDialog.Builder(context);
            b.setTitle(R.string.account_security_dialog_title);
            b.setIconAttribute(android.R.attr.alertDialogIcon);
            b.setMessage(res.getString(R.string.account_security_dialog_content_fmt, accountName));
            b.setPositiveButton(R.string.okay_action, this);
            b.setNegativeButton(R.string.cancel_action, this);
            if (Email.DEBUG) {
                Log.d(TAG, "Posting security needed dialog");
            }
            return b.create();
        }

        @Override
        public void onClick(DialogInterface dialog, int which) {
            dismiss();
            AccountSecurity activity = (AccountSecurity) getActivity();
            if (activity.mAccount == null) {
                // Clicked before activity fully restored - probably just monkey - exit quickly
                activity.finish();
                return;
            }
            switch (which) {
                case DialogInterface.BUTTON_POSITIVE:
                    if (Email.DEBUG) {
                        Log.d(TAG, "User accepts; advance to next step");
                    }
                    activity.tryAdvanceSecurity(activity.mAccount);
                    break;
                case DialogInterface.BUTTON_NEGATIVE:
                    if (Email.DEBUG) {
                        Log.d(TAG, "User declines; repost notification");
                    }
                    activity.repostNotification(
                            activity.mAccount, SecurityPolicy.getInstance(activity));
                    activity.finish();
                    break;
            }
        }
    }

    /**
     * Dialog briefly shown in some cases, to indicate the user that the PIN/Password is expiring
     * or has expired.  If the user clicks OK, we launch the password settings screen.
     */
    public static class PasswordExpirationDialog extends DialogFragment
            implements DialogInterface.OnClickListener {
        private static final String BUNDLE_KEY_ACCOUNT_NAME = "account_name";
        private static final String BUNDLE_KEY_EXPIRED = "expired";

        /**
         * Create a new dialog.
         */
        public static PasswordExpirationDialog newInstance(String accountName, boolean expired) {
            final PasswordExpirationDialog dialog = new PasswordExpirationDialog();
            Bundle b = new Bundle();
            b.putString(BUNDLE_KEY_ACCOUNT_NAME, accountName);
            b.putBoolean(BUNDLE_KEY_EXPIRED, expired);
            dialog.setArguments(b);
            return dialog;
        }

        /**
         * Note, this actually creates two slightly different dialogs (for expiring vs. expired)
         */
        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            final String accountName = getArguments().getString(BUNDLE_KEY_ACCOUNT_NAME);
            final boolean expired = getArguments().getBoolean(BUNDLE_KEY_EXPIRED);
            final int titleId = expired
                    ? R.string.password_expired_dialog_title
                    : R.string.password_expire_warning_dialog_title;
            final int contentId = expired
                    ? R.string.password_expired_dialog_content_fmt
                    : R.string.password_expire_warning_dialog_content_fmt;

            final Context context = getActivity();
            final Resources res = context.getResources();
            final AlertDialog.Builder b = new AlertDialog.Builder(context);
            b.setTitle(titleId);
            b.setIconAttribute(android.R.attr.alertDialogIcon);
            b.setMessage(res.getString(contentId, accountName));
            b.setPositiveButton(R.string.okay_action, this);
            b.setNegativeButton(R.string.cancel_action, this);
            return b.create();
        }

        @Override
        public void onClick(DialogInterface dialog, int which) {
            dismiss();
            AccountSecurity activity = (AccountSecurity) getActivity();
            if (which == DialogInterface.BUTTON_POSITIVE) {
                Intent intent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
                activity.startActivity(intent);
            }
            activity.finish();
        }
    }
}
