/*
 * Copyright (C) 2019 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.ike.eap.statemachine;

import static com.android.ike.eap.EapAuthenticator.LOG;
import static com.android.ike.eap.message.EapData.EAP_NOTIFICATION;
import static com.android.ike.eap.message.EapMessage.EAP_CODE_FAILURE;
import static com.android.ike.eap.message.EapMessage.EAP_CODE_SUCCESS;

import android.annotation.Nullable;

import com.android.ike.eap.EapResult;
import com.android.ike.eap.EapResult.EapError;
import com.android.ike.eap.EapResult.EapFailure;
import com.android.ike.eap.exceptions.EapInvalidRequestException;
import com.android.ike.eap.message.EapData.EapMethod;
import com.android.ike.eap.message.EapMessage;
import com.android.ike.utils.SimpleStateMachine;
import com.android.internal.annotations.VisibleForTesting;

/**
 * EapMethodStateMachine is an abstract class representing a state machine for EAP Method
 * implementations.
 */
public abstract class EapMethodStateMachine extends SimpleStateMachine<EapMessage, EapResult> {
    /**
     * Returns the EAP Method type for this EapMethodStateMachine implementation.
     *
     * @return the IANA value for the EAP Method represented by this EapMethodStateMachine
     */
    @EapMethod
    abstract int getEapMethod();

    @VisibleForTesting
    protected SimpleState getState() {
        return mState;
    }

    @VisibleForTesting
    protected void transitionTo(EapMethodState newState) {
        LOG.d(
                this.getClass().getSimpleName(),
                "Transitioning from " + mState.getClass().getSimpleName()
                        + " to " + newState.getClass().getSimpleName());
        super.transitionTo(newState);
    }

    abstract EapResult handleEapNotification(String tag, EapMessage message);

    protected abstract class EapMethodState extends SimpleState {
        /**
         * Handles premature EAP-Success and EAP-Failure messages, as well as EAP-Notification
         * messages.
         *
         * @param tag the String logging tag to be used while handing message
         * @param message the EapMessage to be checked for early Success/Failure/Notification
         *                messages
         * @return the EapResult generated from handling the give EapMessage, or null if the message
         * Type matches that of the current EAP method
         */
        @Nullable
        EapResult handleEapSuccessFailureNotification(String tag, EapMessage message) {
            if (message.eapCode == EAP_CODE_SUCCESS) {
                // EAP-SUCCESS is required to be the last EAP message sent during the EAP protocol,
                // so receiving a premature SUCCESS message is an unrecoverable error.
                return new EapError(
                        new EapInvalidRequestException(
                                "Received an EAP-Success in the " + tag));
            } else if (message.eapCode == EAP_CODE_FAILURE) {
                transitionTo(new EapAkaMethodStateMachine.FinalState());
                return new EapFailure();
            } else if (message.eapData.eapType == EAP_NOTIFICATION) {
                return handleEapNotification(tag, message);
            } else if (message.eapData.eapType != getEapMethod()) {
                return new EapError(new EapInvalidRequestException(
                        "Expected EAP Type " + getEapMethod()
                                + ", received " + message.eapData.eapType));
            }

            return null;
        }
    }

    protected class FinalState extends EapMethodState {
        @Override
        public EapResult process(EapMessage msg) {
            return new EapError(
                    new IllegalStateException("Attempting to process from a FinalState"));
        }
    }
}
