/*
 * Copyright 2015 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.intentperf;

import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onlab.osgi.ServiceDirectory;
import org.onosproject.intentperf.IntentPerfCollector.Sample;
import org.onosproject.ui.RequestHandler;
import org.onosproject.ui.UiConnection;
import org.onosproject.ui.UiExtension;
import org.onosproject.ui.UiExtensionService;
import org.onosproject.ui.UiMessageHandler;
import org.onosproject.ui.UiView;

import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import static java.util.Collections.synchronizedSet;
import static org.onosproject.ui.UiView.Category.OTHER;

/**
 * Mechanism to stream data to the GUI.
 */
@Component(immediate = true, enabled = true)
@Service(value = IntentPerfUi.class)
public class IntentPerfUi {

    private static final String INTENT_PERF_START = "intentPerfStart";
    private static final String INTENT_PERF_STOP = "intentPerfStop";

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected UiExtensionService uiExtensionService;

    private final Set<StreamingControl> handlers = synchronizedSet(new HashSet<>());

    private List<UiView> views = ImmutableList.of(
            new UiView(OTHER, "intentPerf", "Intent Performance")
    );

    private UiExtension uiExtension =
            new UiExtension.Builder(getClass().getClassLoader(), views)
                .messageHandlerFactory(this::newHandlers)
                .build();

    private IntentPerfCollector collector;

    @Activate
    protected void activate() {
        uiExtensionService.register(uiExtension);
    }

    @Deactivate
    protected void deactivate() {
        uiExtensionService.unregister(uiExtension);
    }

    /**
     * Reports a single sample of performance data.
     *
     * @param sample performance sample
     */
    public void reportSample(Sample sample) {
        synchronized (handlers) {
            handlers.forEach(h -> h.send(sample));
        }
    }

    /**
     * Binds the sample collector.
     *
     * @param collector list of headers for future samples
     */
    public void setCollector(IntentPerfCollector collector) {
        this.collector = collector;
    }

    // Creates and returns session specific message handler.
    private Collection<UiMessageHandler> newHandlers() {
        return ImmutableList.of(new StreamingControl());
    }


    // UI Message handlers for turning on/off reporting to a session.
    private class StreamingControl extends UiMessageHandler {

        private boolean streamingEnabled = false;

        @Override
        protected Collection<RequestHandler> createRequestHandlers() {
            return ImmutableSet.of(
                    new IntentPerfStart(),
                    new IntentPerfStop()
            );
        }

        @Override
        public void init(UiConnection connection, ServiceDirectory directory) {
            super.init(connection, directory);
            handlers.add(this);
        }

        @Override
        public void destroy() {
            super.destroy();
            handlers.remove(this);
        }

        private void send(Sample sample) {
            if (streamingEnabled) {
                connection().sendMessage("intentPerfSample", 0, sampleNode(sample));
            }
        }


        private ObjectNode sampleNode(Sample sample) {
            ObjectNode sampleNode = objectNode();
            ArrayNode an = arrayNode();
            sampleNode.put("time", sample.time);
            sampleNode.set("data", an);

            for (double d : sample.data) {
                an.add(d);
            }
            return sampleNode;
        }

        // ======================================================================

        private final class IntentPerfStart extends RequestHandler {

            private IntentPerfStart() {
                super(INTENT_PERF_START);
            }

            @Override
            public void process(long sid, ObjectNode payload) {
                streamingEnabled = true;
                sendInitData();
            }

            private void sendInitData() {
                ObjectNode rootNode = MAPPER.createObjectNode();
                ArrayNode an = MAPPER.createArrayNode();
                ArrayNode sn = MAPPER.createArrayNode();
                rootNode.set("headers", an);
                rootNode.set("samples", sn);

                collector.getSampleHeaders().forEach(an::add);
                collector.getSamples().forEach(s -> sn.add(sampleNode(s)));
                sendMessage("intentPerfInit", 0, rootNode);
            }
        }

        // ======================================================================

        private final class IntentPerfStop extends RequestHandler {

            private IntentPerfStop() {
                super(INTENT_PERF_STOP);
            }

            @Override
            public void process(long sid, ObjectNode payload) {
                streamingEnabled = false;
            }
        }

    }

}
