/*
 * Copyright 2017-present Open Networking Foundation
 *
 * 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 org.opencord.aaa.impl;

import org.onlab.packet.RADIUS;
import org.onlab.packet.RADIUSAttribute;
import org.onosproject.event.AbstractListenerManager;
import org.opencord.aaa.RadiusCommunicator;
import org.opencord.aaa.RadiusOperationalStatusEvent;
import org.opencord.aaa.RadiusOperationalStatusEventDelegate;
import org.opencord.aaa.RadiusOperationalStatusEventListener;
import org.opencord.aaa.RadiusOperationalStatusService;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.slf4j.Logger;

import static org.slf4j.LoggerFactory.getLogger;

@Component(immediate = true)
public class RadiusOperationalStatusManager
        extends AbstractListenerManager<RadiusOperationalStatusEvent, RadiusOperationalStatusEventListener>
        implements RadiusOperationalStatusService {

    private byte[] address;
    private String secret;
    private RadiusCommunicator impl;
    private RadiusOperationalStatusEventDelegate radiusOprStDelegate;

    private long operationalStatusServerTimeoutInMillis;
    private boolean statusServerReqSent;
    private final Logger log = getLogger(getClass());

    private Boolean fakeAccessRequestPacketRecieved = false;
    private long fakeAccessRequestOutTimeInMillis;

    private Boolean serverStatusPacketRecieved = false;
    private long serverStatusOutTimeInMillis;

    private OperationalStatus radiusServerOperationalStatus;

    public static final byte AAA_REQUEST_ID_STATUS_REQUEST = 0;
    public static final byte AAA_REQUEST_ID_FAKE_ACCESS_REQUEST = 1;

    private RadiusOperationalStatusEvaluationMode radiusOperationalStatusEvaluationMode;

    // FIXME the DUMMY_USER should be read from config (or netcfg)
    private static final String DUMMY_USER = new String("user");
    private static final byte RADIUS_CODE_STATUS_REQUEST = (byte) 12;
    private long lastRadiusPacketInTimeInMillis;

    public void setOperationalStatusServerTimeoutInMillis(long operationalStatusServerTimeoutInMillis) {
        this.operationalStatusServerTimeoutInMillis = operationalStatusServerTimeoutInMillis;
    }

    public void setRadiusOperationalStatusEvaluationMode(
        RadiusOperationalStatusEvaluationMode radiusOperationalStatusEvaluationMode) {
        this.radiusOperationalStatusEvaluationMode = radiusOperationalStatusEvaluationMode;
    }

    public RadiusOperationalStatusEventDelegate getRadiusOprStDelegate() {
        return radiusOprStDelegate;
    }

    @Override
    public void setOutTimeInMillis(byte identifier) {
        if (identifier == AAA_REQUEST_ID_STATUS_REQUEST) {
            serverStatusOutTimeInMillis = System.currentTimeMillis();
        } else {
            fakeAccessRequestOutTimeInMillis = System.currentTimeMillis();
        }
    }

    @Override
    public String getRadiusServerOperationalStatus() {
        return radiusServerOperationalStatus.toString();
    }

    @Activate
    public void activate() {
        radiusOprStDelegate = new InternalRadiusOperationalStatusDelegate();
        eventDispatcher.addSink(RadiusOperationalStatusEvent.class, listenerRegistry);
        radiusServerOperationalStatus = OperationalStatus.UNKNOWN;
    }

    public void setStatusServerReqSent(boolean statusServerReqSent) {
        this.statusServerReqSent = statusServerReqSent;
    }

    @Deactivate
    public void deactivate() {
        eventDispatcher.removeSink(RadiusOperationalStatusEvent.class);
    }

    public void initialize(byte[] address, String secret, RadiusCommunicator impl) {
        this.address = address;
        this.secret = secret;
        this.impl = impl;
    }

    public boolean isRadiusResponseForOperationalStatus(byte identifier) {
        if (identifier == AAA_REQUEST_ID_STATUS_REQUEST || identifier == AAA_REQUEST_ID_FAKE_ACCESS_REQUEST) {
            return true;
        } else {
            lastRadiusPacketInTimeInMillis = System.currentTimeMillis();
            return false;
        }
    }

    public void handleRadiusPacketForOperationalStatus(RADIUS radiusPacket) {
        byte radiusPktIdentifier = radiusPacket.getIdentifier();

        if (radiusPktIdentifier == AAA_REQUEST_ID_STATUS_REQUEST) {
            long serverStatusRttInMillis = System.currentTimeMillis() - serverStatusOutTimeInMillis;
            if (serverStatusRttInMillis < operationalStatusServerTimeoutInMillis) {
                serverStatusPacketRecieved = true;
            }
        } else {
            long fakeAccessRttInMillis = System.currentTimeMillis() - fakeAccessRequestOutTimeInMillis;
            if (fakeAccessRttInMillis < operationalStatusServerTimeoutInMillis) {
                fakeAccessRequestPacketRecieved = true;
            }
        }

        switch (radiusPacket.getCode()) {
            case RADIUS.RADIUS_CODE_ACCESS_ACCEPT:
                synchronized (serverStatusPacketRecieved) {
                    serverStatusPacketRecieved.notify();
                }
                break;
            case RADIUS.RADIUS_CODE_ACCESS_REJECT:
                synchronized (fakeAccessRequestPacketRecieved) {
                    fakeAccessRequestPacketRecieved.notify();
                }
                break;
            default:
                log.warn("Unexpected Radius message for operational status recieved "
                        + "with code: {}", radiusPacket.getCode());
        }
    }

    public void checkServerStatusUsingStatusServerRequest() throws InterruptedException {
        RADIUS radiusStatusServerRequest;
        // identifier = 0 for status server
        radiusStatusServerRequest = new RADIUS(RADIUS_CODE_STATUS_REQUEST, AAA_REQUEST_ID_STATUS_REQUEST);

        radiusStatusServerRequest.setIdentifier(AAA_REQUEST_ID_STATUS_REQUEST);
        radiusStatusServerRequest.setAttribute(RADIUSAttribute.RADIUS_ATTR_USERNAME, DUMMY_USER.getBytes());

        radiusStatusServerRequest.setAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_IP, address);
        radiusStatusServerRequest.addMessageAuthenticator(secret);
        setOutTimeInMillis(radiusStatusServerRequest.getIdentifier());
        impl.sendRadiusPacket(radiusStatusServerRequest, null);
        synchronized (serverStatusPacketRecieved) {
            serverStatusPacketRecieved.wait(operationalStatusServerTimeoutInMillis);
        }
    }

    public void checkServerStatusUsingFakeAccessRequest() throws InterruptedException {
        RADIUS radiusDummyAccessRequest;
        // identifier = 1 for fake accessRequest
        radiusDummyAccessRequest = new RADIUS(RADIUS.RADIUS_CODE_ACCESS_REQUEST, AAA_REQUEST_ID_FAKE_ACCESS_REQUEST);

        radiusDummyAccessRequest.setIdentifier(AAA_REQUEST_ID_FAKE_ACCESS_REQUEST);
        radiusDummyAccessRequest.setAttribute(RADIUSAttribute.RADIUS_ATTR_USERNAME, DUMMY_USER.getBytes());

        radiusDummyAccessRequest.setAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_IP, address);
        radiusDummyAccessRequest.addMessageAuthenticator(secret);
        setOutTimeInMillis(radiusDummyAccessRequest.getIdentifier());
        impl.sendRadiusPacket(radiusDummyAccessRequest, null);
        synchronized (fakeAccessRequestPacketRecieved) {
            fakeAccessRequestPacketRecieved.wait(operationalStatusServerTimeoutInMillis);
        }
    }

    public void checkStatusServerForAccessRequestMode() throws InterruptedException {
        long radiusResponseRecievedTimeDifference = System.currentTimeMillis() - lastRadiusPacketInTimeInMillis;
        if (radiusResponseRecievedTimeDifference > operationalStatusServerTimeoutInMillis) {
            checkServerStatusUsingFakeAccessRequest();
            if (statusServerReqSent && fakeAccessRequestPacketRecieved) {
                radiusServerOperationalStatus = OperationalStatus.IN_USE;
            } else if (statusServerReqSent && !fakeAccessRequestPacketRecieved) {
                radiusServerOperationalStatus = OperationalStatus.UNAVAILABLE;
            } else {
                radiusServerOperationalStatus = OperationalStatus.UNKNOWN;
            }
        } else {
            radiusServerOperationalStatus = OperationalStatus.IN_USE;
        }
    }

    public void checkServerOperationalStatus() {

        try {
            if (radiusOperationalStatusEvaluationMode == RadiusOperationalStatusEvaluationMode.STATUS_REQUEST) {
                // determine operational status by statusServerRequest
                checkServerStatusUsingStatusServerRequest();
                if (statusServerReqSent && serverStatusPacketRecieved) {
                    // if req sent and response recieved
                    radiusServerOperationalStatus = OperationalStatus.IN_USE;
                } else if (statusServerReqSent && !serverStatusPacketRecieved) {
                    radiusServerOperationalStatus = OperationalStatus.UNAVAILABLE;
                } else {
                radiusServerOperationalStatus = OperationalStatus.UNKNOWN;
                }
            } else {
                if (radiusOperationalStatusEvaluationMode == RadiusOperationalStatusEvaluationMode.AUTO) {
                    checkServerStatusUsingStatusServerRequest();
                    if (statusServerReqSent && serverStatusPacketRecieved) {
                        radiusServerOperationalStatus = OperationalStatus.IN_USE;
                    } else {
                        checkStatusServerForAccessRequestMode();
                    }
                } else {
                    checkStatusServerForAccessRequestMode();
                }
            }
            fakeAccessRequestPacketRecieved = false;
            serverStatusPacketRecieved = false;
        } catch (Exception e) {
            log.error("Caught exception while checking radius server status::" + e);
        }
    }

    /**
     * Delegate allowing the RadiusOperationalStatus to notify us of events.
     */
     private class InternalRadiusOperationalStatusDelegate implements RadiusOperationalStatusEventDelegate {
        @Override
        public void notify(RadiusOperationalStatusEvent radiusOperationalStatusEvent) {
            log.debug("Radius Operational Status event {} for {}", radiusOperationalStatusEvent.type(),
                radiusOperationalStatusEvent.subject());
            post(radiusOperationalStatusEvent);
        }
     }

}
