/*
 * 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.provider.nil;

import com.google.common.collect.Sets;
import org.jboss.netty.util.HashedWheelTimer;
import org.jboss.netty.util.Timeout;
import org.jboss.netty.util.TimerTask;
import org.onlab.util.Timer;
import org.onosproject.core.ApplicationId;
import org.onosproject.net.DeviceId;
import org.onosproject.net.flow.CompletedBatchOperation;
import org.onosproject.net.flow.DefaultFlowEntry;
import org.onosproject.net.flow.FlowEntry;
import org.onosproject.net.flow.FlowRule;
import org.onosproject.net.flow.FlowRuleBatchEntry;
import org.onosproject.net.flow.FlowRuleBatchOperation;
import org.onosproject.net.flow.FlowRuleProvider;
import org.onosproject.net.flow.FlowRuleProviderService;
import org.slf4j.Logger;

import java.util.Collections;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;

import static org.slf4j.LoggerFactory.getLogger;

/**
 * Null provider to accept any flow and report them.
 */
class NullFlowRuleProvider extends NullProviders.AbstractNullProvider
        implements FlowRuleProvider {

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

    private ConcurrentMap<DeviceId, Set<FlowEntry>> flowTable = new ConcurrentHashMap<>();

    private FlowRuleProviderService providerService;

    private HashedWheelTimer timer = Timer.getTimer();
    private Timeout timeout;

    /**
     * Starts the flow rule provider simulation.
     *
     * @param providerService flow rule provider service
     */
    void start(FlowRuleProviderService providerService) {
        this.providerService = providerService;
        timeout = timer.newTimeout(new StatisticTask(), 5, TimeUnit.SECONDS);
    }

    /**
     * Stops the flow rule provider simulation.
     */
    void stop() {
        timeout.cancel();
    }

    @Override
    public void applyFlowRule(FlowRule... flowRules) {
        // FIXME: invoke executeBatch
    }

    @Override
    public void removeFlowRule(FlowRule... flowRules) {
        // FIXME: invoke executeBatch
    }

    @Override
    public void removeRulesById(ApplicationId id, FlowRule... flowRules) {
        throw new UnsupportedOperationException("Cannot remove by appId from null provider");
    }

    @Override
    public void executeBatch(FlowRuleBatchOperation batch) {
        // TODO: consider checking mastership
        Set<FlowEntry> entries =
                flowTable.getOrDefault(batch.deviceId(),
                                       Sets.newConcurrentHashSet());
        for (FlowRuleBatchEntry fbe : batch.getOperations()) {
            switch (fbe.operator()) {
                case ADD:
                    entries.add(new DefaultFlowEntry(fbe.target()));
                    break;
                case REMOVE:
                    entries.remove(new DefaultFlowEntry(fbe.target()));
                    break;
                case MODIFY:
                    FlowEntry entry = new DefaultFlowEntry(fbe.target());
                    entries.remove(entry);
                    entries.add(entry);
                    break;
                default:
                    log.error("Unknown flow operation: {}", fbe);
            }
        }
        flowTable.put(batch.deviceId(), entries);
        CompletedBatchOperation op =
                new CompletedBatchOperation(true, Collections.emptySet(),
                                            batch.deviceId());
        providerService.batchOperationCompleted(batch.id(), op);
    }

    // Periodically reports flow rule statistics.
    private class StatisticTask implements TimerTask {
        @Override
        public void run(Timeout to) throws Exception {
            for (DeviceId devId : flowTable.keySet()) {
                Set<FlowEntry> entries =
                        flowTable.getOrDefault(devId, Collections.emptySet());
                providerService.pushFlowMetrics(devId, entries);
            }
            timeout = timer.newTimeout(to.getTask(), 5, TimeUnit.SECONDS);
        }
    }
}
