/*
 * Copyright 2016-present Open Networking Laboratory
 *
 * 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.onosproject.sdxl2;


import org.onosproject.core.ApplicationId;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.edge.EdgePortEvent;
import org.onosproject.net.edge.EdgePortListener;
import org.onosproject.net.edge.EdgePortService;
import org.onosproject.net.intent.IntentEvent;
import org.onosproject.net.intent.IntentListener;
import org.onosproject.net.intent.IntentService;
import org.onosproject.net.intent.IntentState;
import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.Key;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * Implementation of the SdxL2MonitoringService.
 */
public class SdxL2MonitoringManager implements SdxL2MonitoringService {

    private static Logger log = LoggerFactory.getLogger(SdxL2MonitoringManager.class);
    protected ApplicationId appId;
    private final IntentService intentService;
    private final EdgePortService edgePortService;

    /**
     * It is a local cache for the Intents' events.
     */
    private ConcurrentMap<Key, IntentEvent> intentsState;
    /**
     * Last time intentsState has been updated.
     */
    private long lastIntentUpdate;

    /**
     * It is a local cache for the edge ports related events.
     */
    private ConcurrentMap<ConnectPoint, EdgePortEvent> edgeportsState;
    /**
     * Last time edgeportsState has been updated.
     */
    private long lastEdgePortUpdate;

    // A kind of timeout which causes a manual update.
    private static int deltaUpdate = 60000;

    private InternalIntentListener intentListener;
    private InternalEdgePortListener edgePortListener;

    /**
     * Creates an SdxL2MonitoringManager.
     *
     * @param sdxl2id application id.
     * @param intentService reference to the Intent service.
     * @param edgePortService reference to the EdgePort service.
     */
    public SdxL2MonitoringManager(ApplicationId sdxl2id, IntentService intentService, EdgePortService edgePortService) {

        this.appId = sdxl2id;
        this.intentListener = new InternalIntentListener();
        this.edgePortListener = new InternalEdgePortListener();
        this.intentService = intentService;
        this.edgePortService = edgePortService;

        this.intentService.addListener(this.intentListener);
        this.edgePortService.addListener(this.edgePortListener);

        this.intentsState = new ConcurrentHashMap<>();
        this.edgeportsState = new ConcurrentHashMap<>();

        this.lastEdgePortUpdate = 0;
        this.lastIntentUpdate = 0;

        log.info("Started");

    }

    /**
     * Remove listeners.
     */
    public void cleanup() {
        this.intentService.removeListener(intentListener);
        this.edgePortService.removeListener(edgePortListener);
    }

    /**
     * Returns the state of the Intent that has been provided as input.
     *
     * @param intentKey key of the intent;
     * @return the last state of the intent;
     */
    @Override
    public SdxL2State getIntentState(Key intentKey) {
        synchronized (intentsState) {
            IntentEvent event = this.intentsState.get(intentKey);
            long ts = System.currentTimeMillis();
            if (event == null || (ts > lastIntentUpdate && ts - lastIntentUpdate > deltaUpdate)) {
                Intent intent = this.intentService.getIntent(intentKey);
                IntentState intentState = this.intentService.getIntentState(intentKey);
                event = IntentEvent.getEvent(intentState, intent).get();
                intentsState.put(intentKey, event);
                this.lastIntentUpdate = ts;
            }
            return this.getSdxL2State(event.type());
        }
    }

    /**
     * Updates intentsState after an Intent event.
     *
     * @param event the event just happened
     */
    private void processIntentEvent(IntentEvent event) {
        synchronized (intentsState) {
            intentsState.put(event.subject().key(), event);
            this.lastIntentUpdate = System.currentTimeMillis();
        }
    }

    /**
     * Translates the type of the IntentEvent in SdxL2State.
     *
     * @param type the type of event
     * @return the SdxL2State
     */
    private SdxL2State getSdxL2State(IntentEvent.Type type) {
        SdxL2State state;
        switch (type) {
            case INSTALLED:
                state = SdxL2State.ONLINE;
                break;
            case FAILED:
                state = SdxL2State.OFFLINE;
                break;
            case INSTALL_REQ:
            case WITHDRAW_REQ:
            case WITHDRAWN:
            case CORRUPT:
            case PURGED:
            default:
                state = SdxL2State.CHECK;
        }
        return state;
    }

    private class InternalIntentListener implements IntentListener {

        /**
         * Reacts to the specified event.
         *
         * @param event event to be processed
         */
        @Override
        public void event(IntentEvent event) {
            Intent intent = event.subject();
            if (intent.appId().equals(appId)) {
                if (event.type() == IntentEvent.Type.INSTALLED ||
                        event.type() == IntentEvent.Type.FAILED ||
                        event.type() == IntentEvent.Type.WITHDRAWN) {
                    log.info("Intent {} {}", event.subject().key(), event.type());
                }
                processIntentEvent(event);
            }
        }

    }

    /**
     * Returns the state of the EdgePort that has been provided as input.
     *
     * @param edgeport the connect point representing the edge port
     * @return the last state of the edge port;
     */
    @Override
    public SdxL2State getEdgePortState(ConnectPoint edgeport) {
        synchronized (edgeportsState) {
            EdgePortEvent event = this.edgeportsState.get(edgeport);
            long ts = System.currentTimeMillis();
            if (event == null ||
                    (ts > lastEdgePortUpdate && ts - lastEdgePortUpdate > deltaUpdate)) {
                event = new EdgePortEvent(EdgePortEvent.Type.EDGE_PORT_REMOVED, edgeport);
                Iterator<ConnectPoint> cps = this.edgePortService.getEdgePoints(edgeport.deviceId()).iterator();
                while (cps.hasNext()) {
                    if (edgeport.equals(cps.next())) {
                        event = new EdgePortEvent(EdgePortEvent.Type.EDGE_PORT_ADDED, edgeport);
                        break;
                    }
                }
                edgeportsState.put(edgeport, event);
                this.lastEdgePortUpdate = ts;
            }
            return this.getSdxL2State(event.type());
        }
    }

    /**
     * Updates edgeportsState after an EdgePort event.
     *
     * @param event the event just happened
     */
    private void processEdgePortEvent(EdgePortEvent event) {
        synchronized (edgeportsState) {
            edgeportsState.put(event.subject(), event);
            this.lastEdgePortUpdate = System.currentTimeMillis();
        }
    }

    /**
     * Translates the type of EdgePortEvent in SdxL2State.
     *
     * @param type the type of event
     * @return the SdxL2State
     */
    private SdxL2State getSdxL2State(EdgePortEvent.Type type) {
        return type == EdgePortEvent.Type.EDGE_PORT_ADDED ? SdxL2State.ONLINE : SdxL2State.OFFLINE;
    }

    private class InternalEdgePortListener implements EdgePortListener {

        /**
         * Reacts to the specified event.
         *
         * @param event event to be processed
         */
        @Override
        public void event(EdgePortEvent event) {
            ConnectPoint cp = event.subject();
            log.info("ConnectPoint {}/{} {}", cp.elementId().toString(), cp.port().toString(), event.type().toString());
            processEdgePortEvent(event);

        }

    }

}
