/*
 * Copyright 2014 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.onlab.onos.store.trivial.impl;

import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

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.Service;
import org.onlab.onos.net.AnnotationKeys;
import org.onlab.onos.net.Annotations;
import org.onlab.onos.net.Link;
import org.onlab.onos.net.intent.IntentId;
import org.onlab.onos.net.resource.Bandwidth;
import org.onlab.onos.net.resource.BandwidthResourceAllocation;
import org.onlab.onos.net.resource.Lambda;
import org.onlab.onos.net.resource.LambdaResourceAllocation;
import org.onlab.onos.net.resource.LinkResourceAllocations;
import org.onlab.onos.net.resource.LinkResourceEvent;
import org.onlab.onos.net.resource.LinkResourceStore;
import org.onlab.onos.net.resource.ResourceAllocation;
import org.onlab.onos.net.resource.ResourceType;
import org.slf4j.Logger;

import com.google.common.collect.ImmutableList;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static org.slf4j.LoggerFactory.getLogger;

/**
 * Manages link resources using trivial in-memory structures implementation.
 */
@Component(immediate = true)
@Service
public class SimpleLinkResourceStore implements LinkResourceStore {
    private static final int DEFAULT_BANDWIDTH = 1_000;
    private final Logger log = getLogger(getClass());

    private Map<IntentId, LinkResourceAllocations> linkResourceAllocationsMap;
    private Map<Link, Set<LinkResourceAllocations>> allocatedResources;
    private Map<Link, Set<ResourceAllocation>> freeResources;

    @Activate
    public void activate() {
        linkResourceAllocationsMap = new HashMap<>();
        allocatedResources = new HashMap<>();
        freeResources = new HashMap<>();

        log.info("Started");
    }

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

    /**
     * Returns free resources for a given link obtaining from topology
     * information.
     *
     * @param link the target link
     * @return free resources
     */
    private synchronized Set<ResourceAllocation> readOriginalFreeResources(Link link) {
        Annotations annotations = link.annotations();
        Set<ResourceAllocation> allocations = new HashSet<>();

        try {
            int waves = Integer.parseInt(annotations.value(AnnotationKeys.OPTICAL_WAVES));
            for (int i = 1; i <= waves; i++) {
                allocations.add(new LambdaResourceAllocation(Lambda.valueOf(i)));
            }
        } catch (NumberFormatException e) {
            log.debug("No optical.wave annotation on link %s", link);
        }

        int bandwidth = DEFAULT_BANDWIDTH;
        try {
            bandwidth = Integer.parseInt(annotations.value(AnnotationKeys.BANDWIDTH));
        } catch (NumberFormatException e) {
            log.debug("No bandwidth annotation on link %s", link);
        }
        allocations.add(
                new BandwidthResourceAllocation(Bandwidth.valueOf(bandwidth)));
        return allocations;
    }

    /**
     * Finds and returns {@link BandwidthResourceAllocation} object from a given
     * set.
     *
     * @param freeRes a set of ResourceAllocation object.
     * @return {@link BandwidthResourceAllocation} object if found, otherwise
     *         {@link BandwidthResourceAllocation} object with 0 bandwidth
     *
     */
    private synchronized BandwidthResourceAllocation getBandwidth(
            Set<ResourceAllocation> freeRes) {
        for (ResourceAllocation res : freeRes) {
            if (res.type() == ResourceType.BANDWIDTH) {
                return (BandwidthResourceAllocation) res;
            }
        }
        return new BandwidthResourceAllocation(Bandwidth.valueOf(0));
    }

    /**
     * Subtracts given resources from free resources for given link.
     *
     * @param link the target link
     * @param allocations the resources to be subtracted
     */
    private synchronized void subtractFreeResources(Link link,
            LinkResourceAllocations allocations) {
        // TODO Use lock or version for updating freeResources.
        checkNotNull(link);
        Set<ResourceAllocation> freeRes = new HashSet<>(getFreeResources(link));
        Set<ResourceAllocation> subRes = allocations.getResourceAllocation(link);
        for (ResourceAllocation res : subRes) {
            switch (res.type()) {
            case BANDWIDTH:
                BandwidthResourceAllocation ba = getBandwidth(freeRes);
                double requestedBandwidth =
                        ((BandwidthResourceAllocation) res).bandwidth().toDouble();
                double newBandwidth = ba.bandwidth().toDouble() - requestedBandwidth;
                checkState(newBandwidth >= 0.0);
                freeRes.remove(ba);
                freeRes.add(new BandwidthResourceAllocation(
                        Bandwidth.valueOf(newBandwidth)));
                break;
            case LAMBDA:
                checkState(freeRes.remove(res));
                break;
            default:
                break;
            }
        }
        freeResources.put(link, freeRes);

    }

    /**
     * Adds given resources to free resources for given link.
     *
     * @param link the target link
     * @param allocations the resources to be added
     */
    private synchronized void addFreeResources(Link link,
            LinkResourceAllocations allocations) {
        // TODO Use lock or version for updating freeResources.
        Set<ResourceAllocation> freeRes = new HashSet<>(getFreeResources(link));
        Set<ResourceAllocation> addRes = allocations.getResourceAllocation(link);
        for (ResourceAllocation res : addRes) {
            switch (res.type()) {
            case BANDWIDTH:
                BandwidthResourceAllocation ba = getBandwidth(freeRes);
                double requestedBandwidth =
                        ((BandwidthResourceAllocation) res).bandwidth().toDouble();
                double newBandwidth = ba.bandwidth().toDouble() + requestedBandwidth;
                freeRes.remove(ba);
                freeRes.add(new BandwidthResourceAllocation(
                        Bandwidth.valueOf(newBandwidth)));
                break;
            case LAMBDA:
                checkState(freeRes.add(res));
                break;
            default:
                break;
            }
        }
        freeResources.put(link, freeRes);
    }

    @Override
    public synchronized Set<ResourceAllocation> getFreeResources(Link link) {
        checkNotNull(link);
        Set<ResourceAllocation> freeRes = freeResources.get(link);
        if (freeRes == null) {
            freeRes = readOriginalFreeResources(link);
        }

        return freeRes;
    }

    @Override
    public synchronized void allocateResources(LinkResourceAllocations allocations) {
        checkNotNull(allocations);
        linkResourceAllocationsMap.put(allocations.intendId(), allocations);
        for (Link link : allocations.links()) {
            subtractFreeResources(link, allocations);
            Set<LinkResourceAllocations> linkAllocs = allocatedResources.get(link);
            if (linkAllocs == null) {
                linkAllocs = new HashSet<>();
            }
            linkAllocs.add(allocations);
            allocatedResources.put(link, linkAllocs);
        }
    }

    @Override
    public synchronized LinkResourceEvent releaseResources(LinkResourceAllocations allocations) {
        checkNotNull(allocations);
        linkResourceAllocationsMap.remove(allocations.intendId());
        for (Link link : allocations.links()) {
            addFreeResources(link, allocations);
            Set<LinkResourceAllocations> linkAllocs = allocatedResources.get(link);
            if (linkAllocs == null) {
                log.error("Missing resource allocation.");
            } else {
                linkAllocs.remove(allocations);
            }
            allocatedResources.put(link, linkAllocs);
        }

        final List<LinkResourceAllocations> releasedResources =
                ImmutableList.of(allocations);

        return new LinkResourceEvent(
                LinkResourceEvent.Type.ADDITIONAL_RESOURCES_AVAILABLE,
                releasedResources);
    }

    @Override
    public synchronized LinkResourceAllocations getAllocations(IntentId intentId) {
        checkNotNull(intentId);
        return linkResourceAllocationsMap.get(intentId);
    }

    @Override
    public synchronized Iterable<LinkResourceAllocations> getAllocations(Link link) {
        checkNotNull(link);
        Set<LinkResourceAllocations> result = allocatedResources.get(link);
        if (result == null) {
            result = Collections.emptySet();
        }
        return Collections.unmodifiableSet(result);
    }

    @Override
    public synchronized Iterable<LinkResourceAllocations> getAllocations() {
        return Collections.unmodifiableCollection(linkResourceAllocationsMap.values());
    }


}
