/*
 * Copyright 2019-2024 Open Networking Foundation (ONF) and the ONF Contributors
 *
 * 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.bng.impl;

import org.glassfish.jersey.internal.guava.Sets;
import org.onlab.util.Tools;
import org.onosproject.cfg.ComponentConfigService;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.store.service.StorageService;
import org.opencord.bng.BngAttachment;
import org.opencord.bng.BngService;
import org.opencord.bng.PppoeBngAttachment;
import org.opencord.bng.PppoeBngControlHandler;
import org.opencord.bng.PppoeEvent;
import org.opencord.bng.PppoeEventListener;
import org.opencord.bng.PppoeEventSubject;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Modified;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Dictionary;
import java.util.Properties;
import java.util.Set;

import static org.opencord.bng.impl.OsgiPropertyConstants.ENABLE_LOCAL_EVENT_HANDLER;
import static org.opencord.bng.impl.OsgiPropertyConstants.ENABLE_LOCAL_EVENT_HANDLER_DEFAULT;

/**
 * Service to intercept the PPPoE Handler events and trigger the creation of a
 * new attachment in BNG service.
 */
@Component(immediate = true,
        property = {
                ENABLE_LOCAL_EVENT_HANDLER + ":Boolean=" + ENABLE_LOCAL_EVENT_HANDLER_DEFAULT,
        }
)
public class SimpleAttachmentEventHandler {

    private static final String ATTACHMENT_ID_GENERATOR_NAME = "SIMPLE_ATTACHMENT_EVENT_HANDLER_ATTACHMENT_ID";
    private final Logger log = LoggerFactory.getLogger(getClass());

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected ComponentConfigService componentConfigService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected PppoeBngControlHandler pppoEHandlerRelay;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected BngService bngService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected CoreService coreService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected StorageService storageService;

    /**
     * Whether to enable of not the local attachment event handler, for debugging/development.
     */
    private boolean enableLocalEventHandler = ENABLE_LOCAL_EVENT_HANDLER_DEFAULT;
    private InternalPppoeEvent pppoeEventListener = new InternalPppoeEvent();

    // Map to store the attachment that this component has submitted through the BNG Service
    private Set<String> addedAttachmentKeys;

    private ApplicationId appId;

    @Activate
    protected void activate() {
        appId = coreService.getAppId(BngManager.BNG_APP);
        addedAttachmentKeys = Sets.newHashSet();
        componentConfigService.registerProperties(getClass());
        pppoEHandlerRelay.addListener(pppoeEventListener);
        log.info("Simple Attachment Event Handler STARTED");
    }

    @Modified
    public void modified(ComponentContext context) {
        Dictionary<?, ?> properties = context != null ? context.getProperties() : new Properties();

        Boolean localEvent = Tools.isPropertyEnabled(properties, ENABLE_LOCAL_EVENT_HANDLER);
        if (localEvent != null) {
            enableLocalEventHandler = localEvent;
        }
    }

    @Deactivate
    protected void deactivate() {
        pppoEHandlerRelay.removeListener(pppoeEventListener);
        addedAttachmentKeys = null;
        componentConfigService.unregisterProperties(getClass(), false);
        log.info("Simple Attachment Event Handler STOPPED");
    }

    /**
     * Listener for BNG Attachment event for PPPoE attachments.
     */
    class InternalPppoeEvent implements PppoeEventListener {
        @Override
        public void event(PppoeEvent event) {
            PppoeEventSubject eventInfo = event.subject();
            String attachmentKey = BngUtils.calculateBngAttachmentKey(eventInfo);
            switch (event.type()) {
                case IPCP_CONF_ACK:
                    log.debug("Received IPCP_CONF_ACK event, submit a new attachment");
                    log.debug(eventInfo.toString());
                    BngAttachment newAttachment = PppoeBngAttachment.builder()
                            .withPppoeSessionId(eventInfo.getSessionId())
                            .withApplicationId(appId)
                            .withCTag(eventInfo.getcTag())
                            .withSTag(eventInfo.getsTag())
                            .withIpAddress(eventInfo.getIpAddress())
                            .withMacAddress(eventInfo.getMacAddress())
                            .withOnuSerial(eventInfo.getOnuSerialNumber())
                            .withOltConnectPoint(eventInfo.getOltConnectPoint())
                            .lineActivated(true)
                            .build();
                    if (!addedAttachmentKeys.add(attachmentKey)) {
                        log.warn("Attachment ID already present. Re-submit the attachment");
                    }
                    bngService.setupAttachment(attachmentKey, newAttachment);
                    break;

                case SESSION_TERMINATION:
                    attachmentKey =  BngUtils.calculateBngAttachmentKey(eventInfo);
                    log.debug("Received SESSION_TERMINATION event, remove the attachment {}",
                              attachmentKey);
                    if (!addedAttachmentKeys.remove(attachmentKey)) {
                        log.debug("Received SESSION_TERMINATION event, for attachment {} " +
                                          "but attachment not present in local store", attachmentKey);
                    } else {
                        log.debug("Received SESSION_TERMINATION event, remove the attachment {}",
                                  attachmentKey);
                        bngService.removeAttachment(attachmentKey);
                    }
                    break;
                case AUTH_FAILURE:
                case AUTH_REQUEST:
                case AUTH_SUCCESS:
                case SESSION_INIT:
                case IPCP_CONF_REQUEST:
                case SESSION_CONFIRMATION:
                    log.debug("Received event {}, nothing to do here.", event.type().toString());
                    break;
                default:
                    throw new IllegalStateException("Unexpected value: " + event.type() +
                                                            ", for attachment: " + attachmentKey);
            }
        }

        @Override
        public boolean isRelevant(PppoeEvent event) {
            return enableLocalEventHandler &&
                    event.subject().getClass().equals(PppoeEventSubject.class);
        }
    }
}
