/*
 * 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.incubator.net.domain.impl;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import com.google.common.collect.Sets;
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.graph.AdjacencyListsGraph;
import org.onlab.graph.Graph;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.incubator.net.config.NetworkConfigEvent;
import org.onosproject.incubator.net.config.NetworkConfigListener;
import org.onosproject.incubator.net.config.NetworkConfigService;
import org.onosproject.incubator.net.domain.DomainEdge;
import org.onosproject.incubator.net.domain.DomainVertex;
import org.onosproject.incubator.net.domain.IntentDomain;
import org.onosproject.incubator.net.domain.IntentDomainAdminService;
import org.onosproject.incubator.net.domain.IntentDomainConfig;
import org.onosproject.incubator.net.domain.IntentDomainId;
import org.onosproject.incubator.net.domain.IntentDomainListener;
import org.onosproject.incubator.net.domain.IntentDomainProvider;
import org.onosproject.incubator.net.domain.IntentDomainService;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DeviceId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;
import java.util.stream.Collectors;

/**
 * Implementation of the intent domain service.
 */
@Component(immediate = true)
@Service
public class IntentDomainManager
        implements IntentDomainService, IntentDomainAdminService {

    private final Logger log = LoggerFactory.getLogger(getClass());

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

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected NetworkConfigService configService;

    private NetworkConfigListener cfgListener = new InternalConfigListener();

    private final ConcurrentMap<IntentDomainId, IntentDomain> domains = Maps.newConcurrentMap();

    private final Multimap<String, IntentDomainId> appToDomain =
            Multimaps.synchronizedSetMultimap(HashMultimap.<String, IntentDomainId>create());

    private Graph<DomainVertex, DomainEdge> graph;

    @Activate
    protected void activate() {
        configService.addListener(cfgListener);
        configService.getSubjects(IntentDomainId.class, IntentDomainConfig.class)
                     .forEach(this::processConfig);
        graph = buildGraph();
        log.debug("Graph: {}", graph);
        log.info("Started");
    }

    private void processConfig(IntentDomainId intentDomainId) {
        IntentDomainConfig cfg = configService.getConfig(intentDomainId,
                                                         IntentDomainConfig.class);

        domains.put(intentDomainId, createDomain(intentDomainId, cfg));
        appToDomain.put(cfg.applicationName(), intentDomainId);
    }

    private IntentDomain createDomain(IntentDomainId id, IntentDomainConfig cfg) {
        return new IntentDomain(id, cfg.domainName(), cfg.internalDevices(), cfg.edgePorts());
    }

    private Graph<DomainVertex, DomainEdge> buildGraph() {
        Set<DomainVertex> vertices = Sets.newHashSet();
        Set<DomainEdge> edges = Sets.newHashSet();

        Map<DeviceId, DomainVertex> deviceVertices = Maps.newHashMap();
        domains.forEach((id, domain) -> {
            DomainVertex domainVertex = new DomainVertex(id);

            // Add vertex for domain
            vertices.add(domainVertex);

            // Add vertices for connection devices
            domain.edgePorts().stream()
                  .map(ConnectPoint::deviceId)
                  .collect(Collectors.toSet())
                    .forEach(did -> deviceVertices.putIfAbsent(did, new DomainVertex(did)));

            // Add bi-directional edges between each domain and connection device
            domain.edgePorts().forEach(cp -> {
                DomainVertex deviceVertex = deviceVertices.get(cp.deviceId());
                edges.add(new DomainEdge(domainVertex, deviceVertex, cp));
                edges.add(new DomainEdge(deviceVertex, domainVertex, cp));
            });
        });

        vertices.addAll(deviceVertices.values());
        //FIXME verify graph integrity...
        return new AdjacencyListsGraph<>(vertices, edges);
    }

    @Deactivate
    protected void deactivate() {
        configService.removeListener(cfgListener);
        log.info("Stopped");
    }

    @Override
    public IntentDomain getDomain(IntentDomainId id) {
        return domains.get(id);
    }

    @Override
    public Set<IntentDomain> getDomains() {
        return ImmutableSet.copyOf(domains.values());
    }

    @Override
    public Set<IntentDomain> getDomains(DeviceId deviceId) {
        return domains.values().stream()
                .filter(domain ->
                                domain.internalDevices().contains(deviceId) ||
                                domain.edgePorts().stream()
                                        .map(ConnectPoint::deviceId)
                                        .anyMatch(d -> d.equals(deviceId)))
                .collect(Collectors.toSet());
    }

    @Override
    public Graph<DomainVertex, DomainEdge> getDomainGraph() {
        return graph;
    }

    @Override
    public void addListener(IntentDomainListener listener) {
        //TODO slide in AbstractListenerManager
    }

    @Override
    public void removeListener(IntentDomainListener listener) {
        //TODO slide in AbstractListenerManager
    }

    @Override
    public void registerApplication(ApplicationId applicationId, IntentDomainProvider provider) {
        appToDomain.get(applicationId.name()).forEach(d -> domains.get(d).setProvider(provider));
    }

    @Override
    public void unregisterApplication(ApplicationId applicationId) {
        appToDomain.get(applicationId.name()).forEach(d -> domains.get(d).unsetProvider());
    }

    private class InternalConfigListener implements NetworkConfigListener {
        @Override
        public void event(NetworkConfigEvent event) {
            switch (event.type()) {
                case CONFIG_ADDED:
                case CONFIG_UPDATED:
                    processConfig((IntentDomainId) event.subject());
                    graph = buildGraph();
                    log.debug("Graph: {}", graph);
                    break;

                case CONFIG_REGISTERED:
                case CONFIG_UNREGISTERED:
                case CONFIG_REMOVED:
                default:
                    //TODO
                    break;
            }
        }

        @Override
        public boolean isRelevant(NetworkConfigEvent event) {
            return event.configClass().equals(IntentDomainConfig.class);
        }
    }
}
