/*
 * 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.phone.vvm.omtp.protocol;

import android.annotation.IntDef;
import android.content.Context;
import android.provider.VoicemailContract.Status;
import android.telecom.PhoneAccountHandle;
import android.util.Log;

import com.android.phone.VoicemailStatus;
import com.android.phone.settings.VoicemailChangePinActivity;
import com.android.phone.vvm.omtp.DefaultOmtpEventHandler;
import com.android.phone.vvm.omtp.OmtpEvents;
import com.android.phone.vvm.omtp.OmtpEvents.Type;
import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * Handles {@link OmtpEvents} when {@link Vvm3Protocol} is being used. This handler writes custom
 * error codes into the voicemail status table so support on the dialer side is required.
 *
 * TODO(b/29577838) disable VVM3 by default so support on system dialer can be ensured.
 */
public class Vvm3EventHandler {

    private static final String TAG = "Vvm3EventHandler";

    @Retention(RetentionPolicy.SOURCE)
    @IntDef({VMS_DNS_FAILURE, VMG_DNS_FAILURE, SPG_DNS_FAILURE, VMS_NO_CELLULAR, VMG_NO_CELLULAR,
            SPG_NO_CELLULAR, VMS_TIMEOUT, VMG_TIMEOUT, STATUS_SMS_TIMEOUT, SUBSCRIBER_BLOCKED,
            UNKNOWN_USER, UNKNOWN_DEVICE, INVALID_PASSWORD, MAILBOX_NOT_INITIALIZED,
            SERVICE_NOT_PROVISIONED, SERVICE_NOT_ACTIVATED, USER_BLOCKED, IMAP_GETQUOTA_ERROR,
            IMAP_SELECT_ERROR, IMAP_ERROR, VMG_INTERNAL_ERROR, VMG_DB_ERROR,
            VMG_COMMUNICATION_ERROR, SPG_URL_NOT_FOUND, VMG_UNKNOWN_ERROR, PIN_NOT_SET})
    public @interface ErrorCode {

    }

    public static final int VMS_DNS_FAILURE = -9001;
    public static final int VMG_DNS_FAILURE = -9002;
    public static final int SPG_DNS_FAILURE = -9003;
    public static final int VMS_NO_CELLULAR = -9004;
    public static final int VMG_NO_CELLULAR = -9005;
    public static final int SPG_NO_CELLULAR = -9006;
    public static final int VMS_TIMEOUT = -9007;
    public static final int VMG_TIMEOUT = -9008;
    public static final int STATUS_SMS_TIMEOUT = -9009;

    public static final int SUBSCRIBER_BLOCKED = -9990;
    public static final int UNKNOWN_USER = -9991;
    public static final int UNKNOWN_DEVICE = -9992;
    public static final int INVALID_PASSWORD = -9993;
    public static final int MAILBOX_NOT_INITIALIZED = -9994;
    public static final int SERVICE_NOT_PROVISIONED = -9995;
    public static final int SERVICE_NOT_ACTIVATED = -9996;
    public static final int USER_BLOCKED = -9998;
    public static final int IMAP_GETQUOTA_ERROR = -9997;
    public static final int IMAP_SELECT_ERROR = -9989;
    public static final int IMAP_ERROR = -9999;

    public static final int VMG_INTERNAL_ERROR = -101;
    public static final int VMG_DB_ERROR = -102;
    public static final int VMG_COMMUNICATION_ERROR = -103;
    public static final int SPG_URL_NOT_FOUND = -301;

    // Non VVM3 codes:
    public static final int VMG_UNKNOWN_ERROR = -1;
    public static final int PIN_NOT_SET = -100;
    // STATUS SMS returned st=U and rc!=2. The user cannot be provisioned and must contact customer
    // support.
    public static final int SUBSCRIBER_UNKNOWN = -99;


    public static void handleEvent(Context context, OmtpVvmCarrierConfigHelper config,
        VoicemailStatus.Editor status, OmtpEvents event) {
        boolean handled = false;
        switch (event.getType()) {
            case Type.CONFIGURATION:
                handled = handleConfigurationEvent(context, status, event);
                break;
            case Type.DATA_CHANNEL:
                handled = handleDataChannelEvent(status, event);
                break;
            case Type.NOTIFICATION_CHANNEL:
                handled = handleNotificationChannelEvent(status, event);
                break;
            case Type.OTHER:
                handled = handleOtherEvent(status, event);
                break;
            default:
                com.android.services.telephony.Log
                        .wtf(TAG, "invalid event type " + event.getType() + " for " + event);
        }
        if (!handled) {
            DefaultOmtpEventHandler.handleEvent(context, config, status, event);
        }
    }

    private static boolean handleConfigurationEvent(Context context, VoicemailStatus.Editor status,
        OmtpEvents event) {
        switch (event) {
            case CONFIG_REQUEST_STATUS_SUCCESS:
                if (!isPinRandomized(context, status.getPhoneAccountHandle())) {
                    return false;
                } else {
                    postError(status, PIN_NOT_SET);
                }
                break;
            case CONFIG_ACTIVATING_SUBSEQUENT:
                if (isPinRandomized(context, status.getPhoneAccountHandle())) {
                    status.setConfigurationState(PIN_NOT_SET);
                } else {
                    status.setConfigurationState(Status.CONFIGURATION_STATE_OK);
                }
                status
                        .setNotificationChannelState(Status.NOTIFICATION_CHANNEL_STATE_OK)
                        .setDataChannelState(Status.DATA_CHANNEL_STATE_OK).apply();
                break;
            case CONFIG_DEFAULT_PIN_REPLACED:
                postError(status, PIN_NOT_SET);
                break;
            case CONFIG_STATUS_SMS_TIME_OUT:
                postError(status, STATUS_SMS_TIMEOUT);
                break;
            default:
                return false;
        }
        return true;
    }

    private static boolean handleDataChannelEvent(VoicemailStatus.Editor status, OmtpEvents event) {
        switch (event) {
            case DATA_NO_CONNECTION:
            case DATA_NO_CONNECTION_CELLULAR_REQUIRED:
            case DATA_ALL_SOCKET_CONNECTION_FAILED:
                postError(status, VMS_NO_CELLULAR);
                break;
            case DATA_SSL_INVALID_HOST_NAME:
            case DATA_CANNOT_ESTABLISH_SSL_SESSION:
            case DATA_IOE_ON_OPEN:
                postError(status, VMS_TIMEOUT);
                break;
            case DATA_CANNOT_RESOLVE_HOST_ON_NETWORK:
                postError(status, VMS_DNS_FAILURE);
                break;
            case DATA_BAD_IMAP_CREDENTIAL:
                postError(status, IMAP_ERROR);
                break;
            case DATA_AUTH_UNKNOWN_USER:
                postError(status, UNKNOWN_USER);
                break;
            case DATA_AUTH_UNKNOWN_DEVICE:
                postError(status, UNKNOWN_DEVICE);
                break;
            case DATA_AUTH_INVALID_PASSWORD:
                postError(status, INVALID_PASSWORD);
                break;
            case DATA_AUTH_MAILBOX_NOT_INITIALIZED:
                postError(status, MAILBOX_NOT_INITIALIZED);
                break;
            case DATA_AUTH_SERVICE_NOT_PROVISIONED:
                postError(status, SERVICE_NOT_PROVISIONED);
                break;
            case DATA_AUTH_SERVICE_NOT_ACTIVATED:
                postError(status, SERVICE_NOT_ACTIVATED);
                break;
            case DATA_AUTH_USER_IS_BLOCKED:
                postError(status, USER_BLOCKED);
                break;
            case DATA_REJECTED_SERVER_RESPONSE:
            case DATA_INVALID_INITIAL_SERVER_RESPONSE:
            case DATA_SSL_EXCEPTION:
                postError(status, IMAP_ERROR);
                break;
            default:
                return false;
        }
        return true;
    }

    private static boolean handleNotificationChannelEvent(VoicemailStatus.Editor status,
        OmtpEvents event) {
        return false;
    }

    private static boolean handleOtherEvent(VoicemailStatus.Editor status,
            OmtpEvents event) {
        switch (event) {
            case VVM3_NEW_USER_SETUP_FAILED:
                postError(status, MAILBOX_NOT_INITIALIZED);
                break;
            case VVM3_VMG_DNS_FAILURE:
                postError(status, VMG_DNS_FAILURE);
                break;
            case VVM3_SPG_DNS_FAILURE:
                postError(status, SPG_DNS_FAILURE);
                break;
            case VVM3_VMG_CONNECTION_FAILED:
                postError(status, VMG_NO_CELLULAR);
                break;
            case VVM3_SPG_CONNECTION_FAILED:
                postError(status, SPG_NO_CELLULAR);
                break;
            case VVM3_VMG_TIMEOUT:
                postError(status, VMG_TIMEOUT);
                break;
            case VVM3_SUBSCRIBER_PROVISIONED:
                postError(status, SERVICE_NOT_ACTIVATED);
                break;
            case VVM3_SUBSCRIBER_BLOCKED:
                postError(status, SUBSCRIBER_BLOCKED);
                break;
            case VVM3_SUBSCRIBER_UNKNOWN:
                postError(status, SUBSCRIBER_UNKNOWN);
                break;
            default:
                return false;
        }
        return true;
    }

    private static void postError(VoicemailStatus.Editor editor, @ErrorCode int errorCode) {
        switch (errorCode) {
            case VMG_DNS_FAILURE:
            case SPG_DNS_FAILURE:
            case VMG_NO_CELLULAR:
            case SPG_NO_CELLULAR:
            case VMG_TIMEOUT:
            case SUBSCRIBER_BLOCKED:
            case UNKNOWN_USER:
            case UNKNOWN_DEVICE:
            case INVALID_PASSWORD:
            case MAILBOX_NOT_INITIALIZED:
            case SERVICE_NOT_PROVISIONED:
            case SERVICE_NOT_ACTIVATED:
            case USER_BLOCKED:
            case VMG_UNKNOWN_ERROR:
            case SPG_URL_NOT_FOUND:
            case VMG_INTERNAL_ERROR:
            case VMG_DB_ERROR:
            case VMG_COMMUNICATION_ERROR:
            case PIN_NOT_SET:
            case SUBSCRIBER_UNKNOWN:
                editor.setConfigurationState(errorCode);
                break;
            case VMS_NO_CELLULAR:
            case VMS_DNS_FAILURE:
            case VMS_TIMEOUT:
            case IMAP_GETQUOTA_ERROR:
            case IMAP_SELECT_ERROR:
            case IMAP_ERROR:
                editor.setDataChannelState(errorCode);
                break;
            case STATUS_SMS_TIMEOUT:
                editor.setNotificationChannelState(errorCode);
                break;
            default:
                Log.wtf(TAG, "unknown error code: " + errorCode);
        }
        editor.apply();
    }

    private static boolean isPinRandomized(Context context, PhoneAccountHandle phoneAccountHandle) {
        if (phoneAccountHandle == null) {
            // This should never happen.
            Log.e(TAG, "status editor has null phone account handle");
            return false;
        }
        return VoicemailChangePinActivity.isDefaultOldPinSet(context, phoneAccountHandle);
    }
}
