/*
 * 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.onosproject.routeservice.impl;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.googlecode.concurrenttrees.common.KeyValuePair;
import com.googlecode.concurrenttrees.radix.node.concrete.DefaultByteArrayNodeFactory;
import com.googlecode.concurrenttrees.radixinverted.ConcurrentInvertedRadixTree;
import com.googlecode.concurrenttrees.radixinverted.InvertedRadixTree;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.util.GuavaCollectors;
import org.onlab.util.Tools;
import org.onosproject.routeservice.ResolvedRoute;
import org.onosproject.routeservice.RouteEvent;
import org.onosproject.routeservice.RouteTableId;

import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import static org.onosproject.routeservice.RouteTools.createBinaryString;

/**
 * Stores routes that have been resolved.
 */
public class DefaultResolvedRouteStore implements ResolvedRouteStore {

    private Map<RouteTableId, RouteTable> routeTables;
    private static final RouteTableId IPV4 = new RouteTableId("ipv4");
    private static final RouteTableId IPV6 = new RouteTableId("ipv6");

    /**
     * Creates a new resolved route store.
     */
    public DefaultResolvedRouteStore() {
        routeTables = new ConcurrentHashMap<>();

        routeTables.put(IPV4, new RouteTable());
        routeTables.put(IPV6, new RouteTable());
    }

    @Override
    public RouteEvent updateRoute(ResolvedRoute route, Set<ResolvedRoute> alternatives) {
        return getDefaultRouteTable(route).update(route, alternatives);
    }

    @Override
    public RouteEvent removeRoute(IpPrefix prefix) {
        RouteTable table = getDefaultRouteTable(prefix.address());
        return table.remove(prefix);
    }

    @Override
    public Set<RouteTableId> getRouteTables() {
        return routeTables.keySet();
    }

    @Override
    public Collection<ResolvedRoute> getRoutes(RouteTableId table) {
        RouteTable routeTable = routeTables.get(table);
        if (routeTable == null) {
            return Collections.emptySet();
        }
        return routeTable.getRoutes();
    }

    @Override
    public Optional<ResolvedRoute> getRoute(IpPrefix prefix) {
        return getDefaultRouteTable(prefix.address()).getRoute(prefix);
    }

    @Override
    public Collection<ResolvedRoute> getAllRoutes(IpPrefix prefix) {
        return getDefaultRouteTable(prefix.address()).getAllRoutes(prefix);
    }

    @Override
    public Optional<ResolvedRoute> longestPrefixMatch(IpAddress ip) {
        return getDefaultRouteTable(ip).longestPrefixMatch(ip);
    }

    private RouteTable getDefaultRouteTable(ResolvedRoute route) {
        return getDefaultRouteTable(route.prefix().address());
    }

    private RouteTable getDefaultRouteTable(IpAddress ip) {
        RouteTableId routeTableId = (ip.isIp4()) ? IPV4 : IPV6;
        return routeTables.get(routeTableId);
    }

    /**
     * Route table into which routes can be placed.
     */
    private class RouteTable {
        private final InvertedRadixTree<ResolvedRoute> routeTable;
        private final Map<IpPrefix, Set<ResolvedRoute>> alternativeRoutes;

        /**
         * Creates a new route table.
         */
        public RouteTable() {
            routeTable = new ConcurrentInvertedRadixTree<>(
                    new DefaultByteArrayNodeFactory());

            alternativeRoutes = Maps.newHashMap();
        }

        /**
         * Adds or updates the route in the route table.
         *
         * @param route route to update
         * @param alternatives alternative routes
         */
        public RouteEvent update(ResolvedRoute route, Set<ResolvedRoute> alternatives) {
            Set<ResolvedRoute> immutableAlternatives = checkAlternatives(route, alternatives);

            synchronized (this) {
                ResolvedRoute oldRoute = routeTable.put(createBinaryString(route.prefix()), route);
                Set<ResolvedRoute> oldRoutes = alternativeRoutes.put(route.prefix(), immutableAlternatives);

                if (!route.equals(oldRoute)) {
                    if (oldRoute == null) {
                        return new RouteEvent(RouteEvent.Type.ROUTE_ADDED, route,
                                immutableAlternatives);
                    } else {
                        return new RouteEvent(RouteEvent.Type.ROUTE_UPDATED, route,
                                oldRoute, immutableAlternatives, oldRoutes);
                    }
                }

                if (!immutableAlternatives.equals(oldRoutes)) {
                    return new RouteEvent(RouteEvent.Type.ALTERNATIVE_ROUTES_CHANGED,
                            route, null, immutableAlternatives, oldRoutes);
                }

                return null;
            }
        }

        /**
         * Checks that the best route is present in the alternatives list and
         * returns an immutable set of alternatives.
         *
         * @param route best route
         * @param alternatives alternatives
         * @return immutable set of alternative routes
         */
        private Set<ResolvedRoute> checkAlternatives(ResolvedRoute route, Set<ResolvedRoute> alternatives) {
            if (!alternatives.contains(route)) {
                return ImmutableSet.<ResolvedRoute>builder()
                        .addAll(alternatives)
                        .add(route)
                        .build();
            } else {
                return ImmutableSet.copyOf(alternatives);
            }
        }

        /**
         * Removes the route from the route table.
         *
         * @param prefix prefix to remove
         */
        public RouteEvent remove(IpPrefix prefix) {
            synchronized (this) {
                String key = createBinaryString(prefix);

                ResolvedRoute route = routeTable.getValueForExactKey(key);
                Set<ResolvedRoute> alternatives = alternativeRoutes.remove(prefix);

                if (route != null) {
                    routeTable.remove(key);
                    return new RouteEvent(RouteEvent.Type.ROUTE_REMOVED, route, alternatives);
                }
                return null;
            }
        }

        /**
         * Returns all routes in the route table.
         *
         * @return all routes
         */
        public Collection<ResolvedRoute> getRoutes() {
            return Tools.stream(routeTable.getKeyValuePairsForKeysStartingWith(""))
                    .map(KeyValuePair::getValue)
                    .collect(GuavaCollectors.toImmutableList());
        }

        /**
         * Returns the best route for the given prefix, if one exists.
         *
         * @param prefix IP prefix
         * @return best route
         */
        public Optional<ResolvedRoute> getRoute(IpPrefix prefix) {
            return Optional.ofNullable(routeTable.getValueForExactKey(createBinaryString(prefix)));
        }

        public Collection<ResolvedRoute> getAllRoutes(IpPrefix prefix) {
            return alternativeRoutes.getOrDefault(prefix, Collections.emptySet());
        }

        /**
         * Performs a longest prefix match with the given IP in the route table.
         *
         * @param ip IP address to look up
         * @return most specific prefix containing the given
         */
        public Optional<ResolvedRoute> longestPrefixMatch(IpAddress ip) {
            return Tools.stream(routeTable.getValuesForKeysPrefixing(createBinaryString(ip.toIpPrefix())))
                    .reduce((a, b) -> b); // reduces to the last element in the stream
        }
    }
}
