/*
 * Copyright 2016 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.primitives.impl;

import static org.slf4j.LoggerFactory.getLogger;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.function.Supplier;
import java.util.stream.Collectors;

import org.apache.commons.collections.ListUtils;
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.onosproject.cluster.ClusterService;
import org.onosproject.cluster.PartitionId;
import org.onosproject.persistence.PersistenceService;
import org.onosproject.store.cluster.messaging.ClusterCommunicationService;
import org.onosproject.store.primitives.DistributedPrimitiveCreator;
import org.onosproject.store.primitives.MapUpdate;
import org.onosproject.store.primitives.PartitionAdminService;
import org.onosproject.store.primitives.PartitionService;
import org.onosproject.store.primitives.TransactionId;
import org.onosproject.store.serializers.KryoNamespaces;
import org.onosproject.store.service.AsyncConsistentMap;
import org.onosproject.store.service.AtomicCounterBuilder;
import org.onosproject.store.service.AtomicValueBuilder;
import org.onosproject.store.service.ConsistentMap;
import org.onosproject.store.service.ConsistentMapBuilder;
import org.onosproject.store.service.DistributedQueueBuilder;
import org.onosproject.store.service.DistributedSetBuilder;
import org.onosproject.store.service.EventuallyConsistentMapBuilder;
import org.onosproject.store.service.LeaderElectorBuilder;
import org.onosproject.store.service.MapInfo;
import org.onosproject.store.service.PartitionInfo;
import org.onosproject.store.service.Serializer;
import org.onosproject.store.service.StorageAdminService;
import org.onosproject.store.service.StorageService;
import org.onosproject.store.service.TransactionContextBuilder;
import org.slf4j.Logger;

import com.google.common.collect.Maps;
import com.google.common.util.concurrent.Futures;

/**
 * Implementation for {@code StorageService} and {@code StorageAdminService}.
 */
@Service
@Component(immediate = true, enabled = false)
public class StorageManager implements StorageService, StorageAdminService {

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

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected ClusterService clusterService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected ClusterCommunicationService clusterCommunicator;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected PersistenceService persistenceService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected PartitionService partitionService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected PartitionAdminService partitionAdminService;

    private final Supplier<TransactionId> transactionIdGenerator =
            () -> TransactionId.from(UUID.randomUUID().toString());
    private DistributedPrimitiveCreator basePrimitiveCreator;
    private DistributedPrimitiveCreator federatedPrimitiveCreator;
    private AsyncConsistentMap<TransactionId, Transaction.State> transactions;
    private TransactionCoordinator transactionCoordinator;

    @Activate
    public void activate() {
        basePrimitiveCreator = partitionService.getDistributedPrimitiveCreator(PartitionId.from(0));
        Map<PartitionId, DistributedPrimitiveCreator> partitionMap = Maps.newHashMap();
        partitionService.getAllPartitionIds().stream()
            .filter(id -> !id.equals(PartitionId.from(0)))
            .forEach(id -> partitionMap.put(id, partitionService.getDistributedPrimitiveCreator(id)));
        federatedPrimitiveCreator = new FederatedDistributedPrimitiveCreator(partitionMap);
        transactions = this.<TransactionId, Transaction.State>consistentMapBuilder()
                    .withName("onos-transactions")
                    .withSerializer(Serializer.using(KryoNamespaces.API,
                            MapUpdate.class,
                            MapUpdate.Type.class,
                            Transaction.class,
                            Transaction.State.class))
                    .buildAsyncMap();
        transactionCoordinator = new TransactionCoordinator(transactions);
        log.info("Started");
    }

    @Deactivate
    public void deactivate() {
        log.info("Stopped");
    }

    @Override
    public <K, V> EventuallyConsistentMapBuilder<K, V> eventuallyConsistentMapBuilder() {
        return new EventuallyConsistentMapBuilderImpl<>(clusterService,
                clusterCommunicator,
                persistenceService);
    }

    @Override
    public <K, V> ConsistentMapBuilder<K, V> consistentMapBuilder() {
        return new NewDefaultConsistentMapBuilder<>(basePrimitiveCreator, federatedPrimitiveCreator);
    }

    @Override
    public <E> DistributedSetBuilder<E> setBuilder() {
        return new DefaultDistributedSetBuilder<>(() -> this.<E, Boolean>consistentMapBuilder());
    }

    @Override
    public <E> DistributedQueueBuilder<E> queueBuilder() {
        // TODO: implement
        throw new UnsupportedOperationException();
    }

    @Override
    public AtomicCounterBuilder atomicCounterBuilder() {
        return new NewDefaultAtomicCounterBuilder(basePrimitiveCreator, federatedPrimitiveCreator);
    }

    @Override
    public <V> AtomicValueBuilder<V> atomicValueBuilder() {
        Supplier<ConsistentMapBuilder<String, byte[]>> mapBuilderSupplier =
                () -> this.<String, byte[]>consistentMapBuilder()
                          .withName("onos-atomic-values")
                          .withMeteringDisabled()
                          .withSerializer(Serializer.using(KryoNamespaces.BASIC));
        return new DefaultAtomicValueBuilder<>(mapBuilderSupplier);
    }

    @Override
    public TransactionContextBuilder transactionContextBuilder() {
        return new NewDefaultTransactionContextBuilder(transactionIdGenerator.get(),
                basePrimitiveCreator,
                federatedPrimitiveCreator,
                transactionCoordinator);
    }

    @Override
    public LeaderElectorBuilder leaderElectorBuilder() {
        return new DefaultLeaderElectorBuilder(basePrimitiveCreator,
                federatedPrimitiveCreator);
    }

    @Override
    public List<MapInfo> getMapInfo() {
        return ListUtils.union(listMapInfo(basePrimitiveCreator), listMapInfo(federatedPrimitiveCreator));
    }

    @Override
    public Map<String, Long> getCounters() {
        Map<String, Long> result = Maps.newHashMap();
        result.putAll(getInMemoryDatabaseCounters());
        result.putAll(getPartitionedDatabaseCounters());
        return result;
    }

    @Override
    public Map<String, Long> getInMemoryDatabaseCounters() {
        return getCounters(basePrimitiveCreator);
    }

    @Override
    public Map<String, Long> getPartitionedDatabaseCounters() {
        return getCounters(federatedPrimitiveCreator);
    }

    public Map<String, Long> getCounters(DistributedPrimitiveCreator creator) {
        Map<String, Long> counters = Maps.newConcurrentMap();
        creator.getAsyncAtomicCounterNames()
               .forEach(name -> counters.put(name, creator.newAsyncCounter(name).asAtomicCounter().get()));
        return counters;
    }

    @Override
    public List<PartitionInfo> getPartitionInfo() {
        return partitionAdminService.partitionInfo();
    }

    @Override
    public Collection<TransactionId> getPendingTransactions() {
        return Futures.getUnchecked(transactions.keySet());
    }

    private List<MapInfo> listMapInfo(DistributedPrimitiveCreator creator) {
        Serializer serializer = Serializer.using(KryoNamespaces.BASIC);
        return creator.getAsyncConsistentMapNames()
        .stream()
        .map(name -> {
            ConsistentMap<String, byte[]> map =
                    creator.<String, byte[]>newAsyncConsistentMap(name, serializer)
                                             .asConsistentMap();
                    return new MapInfo(name, map.size());
        }).collect(Collectors.toList());
    }
}
