/*
 * 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.store.newresource.impl;

import com.google.common.annotations.Beta;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onosproject.net.newresource.ResourceConsumer;
import org.onosproject.net.newresource.ResourcePath;
import org.onosproject.net.newresource.ResourceStore;
import org.onosproject.store.serializers.KryoNamespaces;
import org.onosproject.store.service.ConsistentMap;
import org.onosproject.store.service.Serializer;
import org.onosproject.store.service.StorageService;
import org.onosproject.store.service.TransactionContext;
import org.onosproject.store.service.TransactionException;
import org.onosproject.store.service.TransactionalMap;
import org.onosproject.store.service.Versioned;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;

/**
 * Implementation of ResourceStore using TransactionalMap.
 */
@Component(immediate = true, enabled = false)
@Service
@Beta
public class ConsistentResourceStore implements ResourceStore {
    private static final Logger log = LoggerFactory.getLogger(ConsistentResourceStore.class);

    private static final String CONSUMER_MAP = "onos-resource-consumers";
    private static final String CHILD_MAP = "onos-resource-children";
    private static final Serializer SERIALIZER = Serializer.using(
            Arrays.asList(KryoNamespaces.BASIC, KryoNamespaces.API));

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected StorageService service;

    private ConsistentMap<ResourcePath, ResourceConsumer> consumerMap;
    private ConsistentMap<ResourcePath, List<ResourcePath>> childMap;

    @Activate
    public void activate() {
        consumerMap = service.<ResourcePath, ResourceConsumer>consistentMapBuilder()
                .withName(CONSUMER_MAP)
                .withSerializer(SERIALIZER)
                .build();
        childMap = service.<ResourcePath, List<ResourcePath>>consistentMapBuilder()
                .withName(CHILD_MAP)
                .withSerializer(SERIALIZER)
                .build();
    }

    @Override
    public Optional<ResourceConsumer> getConsumer(ResourcePath resource) {
        checkNotNull(resource);

        Versioned<ResourceConsumer> consumer = consumerMap.get(resource);
        if (consumer == null) {
            return Optional.empty();
        }

        return Optional.of(consumer.value());
    }

    @Override
    public boolean register(ResourcePath resource, List<ResourcePath> children) {
        checkNotNull(resource);
        checkNotNull(children);

        TransactionContext tx = service.transactionContextBuilder().build();
        tx.begin();

        try {
            TransactionalMap<ResourcePath, List<ResourcePath>> childTxMap =
                    tx.getTransactionalMap(CHILD_MAP, SERIALIZER);

            if (!isRegistered(childTxMap, resource)) {
                return abortTransaction(tx);
            }

            if (!appendValue(childTxMap, resource, children)) {
                return abortTransaction(tx);
            }

            return commitTransaction(tx);
        } catch (TransactionException e) {
            log.error("Exception thrown, abort the transaction", e);
            return abortTransaction(tx);
        }
    }

    @Override
    public boolean allocate(List<ResourcePath> resources, ResourceConsumer consumer) {
        checkNotNull(resources);
        checkNotNull(consumer);

        TransactionContext tx = service.transactionContextBuilder().build();
        tx.begin();

        try {
            TransactionalMap<ResourcePath, List<ResourcePath>> childTxMap =
                    tx.getTransactionalMap(CHILD_MAP, SERIALIZER);
            TransactionalMap<ResourcePath, ResourceConsumer> consumerTxMap =
                    tx.getTransactionalMap(CONSUMER_MAP, SERIALIZER);

            for (ResourcePath resource: resources) {
                if (!isRegistered(childTxMap, resource)) {
                    return abortTransaction(tx);
                }

                ResourceConsumer oldValue = consumerTxMap.put(resource, consumer);
                if (oldValue != null) {
                    return abortTransaction(tx);
                }
            }

            return commitTransaction(tx);
        } catch (TransactionException e) {
            log.error("Exception thrown, abort the transaction", e);
            return abortTransaction(tx);
        }
    }

    @Override
    public boolean release(List<ResourcePath> resources, List<ResourceConsumer> consumers) {
        checkNotNull(resources);
        checkNotNull(consumers);
        checkArgument(resources.size() == consumers.size());

        TransactionContext tx = service.transactionContextBuilder().build();
        tx.begin();

        try {
            TransactionalMap<ResourcePath, ResourceConsumer> consumerTxMap =
                    tx.getTransactionalMap(CONSUMER_MAP, SERIALIZER);
            Iterator<ResourcePath> resourceIte = resources.iterator();
            Iterator<ResourceConsumer> consumerIte = consumers.iterator();

            while (resourceIte.hasNext() && consumerIte.hasNext()) {
                ResourcePath resource = resourceIte.next();
                ResourceConsumer consumer = consumerIte.next();

                // if this single release fails (because the resource is allocated to another consumer,
                // the whole release fails
                if (!consumerTxMap.remove(resource, consumer)) {
                    return abortTransaction(tx);
                }
            }

            return commitTransaction(tx);
        } catch (TransactionException e) {
            log.error("Exception thrown, abort the transaction", e);
            return abortTransaction(tx);
        }
    }

    @Override
    public Collection<ResourcePath> getResources(ResourceConsumer consumer) {
        checkNotNull(consumer);

        // NOTE: getting all entries may become performance bottleneck
        // TODO: revisit for better backend data structure
        return consumerMap.entrySet().stream()
                .filter(x -> x.getValue().value().equals(consumer))
                .map(Map.Entry::getKey)
                .collect(Collectors.toList());
    }

    @Override
    public <T> Collection<ResourcePath> getAllocatedResources(ResourcePath parent, Class<T> cls) {
        checkNotNull(parent);
        checkNotNull(cls);

        Versioned<List<ResourcePath>> children = childMap.get(parent);
        if (children == null) {
            return Collections.emptyList();
        }

        return children.value().stream()
                .filter(x -> x.lastComponent().getClass().equals(cls))
                .filter(consumerMap::containsKey)
                .collect(Collectors.toList());
    }

    /**
     * Abort the transaction.
     *
     * @param tx transaction context
     * @return always false
     */
    private boolean abortTransaction(TransactionContext tx) {
        tx.abort();
        return false;
    }

    /**
     * Commit the transaction.
     *
     * @param tx transaction context
     * @return always true
     */
    private boolean commitTransaction(TransactionContext tx) {
        tx.commit();
        return true;
    }

    /**
     * Appends the values to the existing values associated with the specified key.
     *
     * @param map map holding multiple values for a key
     * @param key key specifying values
     * @param values values to be appended
     * @param <K> type of the key
     * @param <V> type of the element of the list
     * @return true if the operation succeeds, false otherwise.
     */
    private <K, V> boolean appendValue(TransactionalMap<K, List<V>> map, K key, List<V> values) {
        List<V> oldValues = map.get(key);
        List<V> newValues;
        if (oldValues == null) {
            newValues = new ArrayList<>(values);
        } else {
            LinkedHashSet<V> newSet = new LinkedHashSet<>(oldValues);
            newSet.addAll(values);
            newValues = new ArrayList<>(newSet);
        }

        return map.replace(key, oldValues, newValues);
    }

    /**
     * Checks if the specified resource is registered as a child of a resource in the map.
     *
     * @param map map storing parent - child relationship of resources
     * @param resource resource to be checked
     * @return true if the resource is registered, false otherwise.
     */
    private boolean isRegistered(TransactionalMap<ResourcePath, List<ResourcePath>> map, ResourcePath resource) {
        // root is always regarded to be registered
        if (!resource.parent().isPresent()) {
            return true;
        }

        List<ResourcePath> value = map.get(resource.parent().get());
        return value != null && value.contains(resource);
    }
}
