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

import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CompletableFuture;

import org.onlab.util.Tools;
import org.onosproject.store.service.AsyncAtomicValue;
import org.onosproject.store.service.AtomicValueEvent;
import org.onosproject.store.service.AtomicValueEventListener;
import org.onosproject.store.service.MapEventListener;
import org.onosproject.store.service.Versioned;

import com.google.common.collect.Sets;

/**
 * Implementation of {@link AsyncAtomicValue} backed by {@link AtomixConsistentMap}.
 */
public class AtomixValue implements AsyncAtomicValue<String> {

    private final String name;
    private final AtomixConsistentMap atomixMap;
    private MapEventListener<String, byte[]> mapEventListener;
    private final Set<AtomicValueEventListener<String>> listeners = Sets.newIdentityHashSet();

    AtomixValue(String name, AtomixConsistentMap atomixMap) {
        this.name = name;
        this.atomixMap = atomixMap;
    }

    @Override
    public CompletableFuture<Boolean> compareAndSet(String expect, String update) {
        return atomixMap.replace(name, Tools.getBytesUtf8(expect), Tools.getBytesUtf8(update));
    }

    @Override
    public CompletableFuture<String> get() {
        return atomixMap.get(name)
                        .thenApply(v -> v != null ? Tools.toStringUtf8(v.value()) : null);
    }

    @Override
    public CompletableFuture<String> getAndSet(String value) {
        return atomixMap.put(name, Tools.getBytesUtf8(value))
                        .thenApply(v -> v != null ? Tools.toStringUtf8(v.value()) : null);
    }

    @Override
    public CompletableFuture<Void> set(String value) {
        return getAndSet(value).thenApply(v -> null);
    }

    @Override
    public CompletableFuture<Void> addListener(AtomicValueEventListener<String> listener) {
        // TODO: synchronization
        if (mapEventListener == null) {
            mapEventListener = event -> {
                Versioned<byte[]> newValue = event.newValue();
                Versioned<byte[]> oldValue = event.oldValue();
                if (Objects.equals(event.key(), name)) {
                    listener.event(new AtomicValueEvent<>(name,
                            newValue == null ? null : Tools.toStringUtf8(newValue.value()),
                            oldValue == null ? null : Tools.toStringUtf8(oldValue.value())));
                }
            };
            return atomixMap.addListener(mapEventListener).whenComplete((r, e) -> {
                if (e == null) {
                    listeners.add(listener);
                } else {
                    mapEventListener = null;
                }
            });
        } else {
            listeners.add(listener);
            return CompletableFuture.completedFuture(null);
        }
    }

    @Override
    public CompletableFuture<Void> removeListener(AtomicValueEventListener<String> listener) {
        // TODO: synchronization
        listeners.remove(listener);
        if (listeners.isEmpty()) {
            return atomixMap.removeListener(mapEventListener);
        } else {
            return CompletableFuture.completedFuture(null);
        }
    }

    @Override
    public String name() {
        return null;
    }
}