/*
 * Copyright 2017-present Open Networking Foundation
 *
 * 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.incubator.net.virtual.impl.provider;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.RemovalCause;
import com.google.common.cache.RemovalNotification;
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.core.IdGenerator;
import org.onosproject.incubator.net.virtual.NetworkId;
import org.onosproject.incubator.net.virtual.provider.AbstractVirtualProvider;
import org.onosproject.incubator.net.virtual.provider.VirtualMeterProvider;
import org.onosproject.incubator.net.virtual.provider.VirtualMeterProviderService;
import org.onosproject.incubator.net.virtual.provider.VirtualProviderRegistryService;
import org.onosproject.net.DeviceId;
import org.onosproject.net.meter.Meter;
import org.onosproject.net.meter.MeterEvent;
import org.onosproject.net.meter.MeterFailReason;
import org.onosproject.net.meter.MeterListener;
import org.onosproject.net.meter.MeterOperation;
import org.onosproject.net.meter.MeterOperations;
import org.onosproject.net.meter.MeterService;
import org.onosproject.net.provider.ProviderId;
import org.slf4j.Logger;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

import static org.slf4j.LoggerFactory.getLogger;

/**
 * Provider to handle meters for virtual networks.
 */
@Component(immediate = true)
@Service
public class DefaultVirtualMeterProvider extends AbstractVirtualProvider
        implements VirtualMeterProvider {

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

    static final long TIMEOUT = 30;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected VirtualProviderRegistryService providerRegistryService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected MeterService meterService;

    private MeterListener internalMeterListener;
    private Cache<Long, VirtualMeterOperation> pendingOperations;
    private IdGenerator idGenerator;

    @Activate
    public void activate() {
        providerRegistryService.registerProvider(this);
        internalMeterListener = new InternalMeterListener();

        idGenerator = getIdGenerator();

        pendingOperations = CacheBuilder.newBuilder()
                .expireAfterWrite(TIMEOUT, TimeUnit.SECONDS)
                .removalListener(
                        (RemovalNotification<Long, VirtualMeterOperation>
                                 notification) -> {
                    if (notification.getCause() == RemovalCause.EXPIRED) {
                        NetworkId networkId = notification.getValue().networkId();
                        MeterOperation op = notification.getValue().operation();

                        VirtualMeterProviderService providerService =
                                (VirtualMeterProviderService) providerRegistryService
                                        .getProviderService(networkId,
                                                            VirtualMeterProvider.class);

                        providerService.meterOperationFailed(op,
                                                             MeterFailReason.TIMEOUT);
                    }
                }).build();

        meterService.addListener(internalMeterListener);

        log.info("Started");
    }

    @Deactivate
    public void deactivate() {
        meterService.removeListener(internalMeterListener);
        providerRegistryService.unregisterProvider(this);
    }

    /**
     * Creates a provider with the identifier.
     */
    public DefaultVirtualMeterProvider() {
        super(new ProviderId("vnet-meter",
                             "org.onosproject.virtual.vnet-meter"));
    }

    @Override
    public void performMeterOperation(NetworkId networkId, DeviceId deviceId,
                                      MeterOperations meterOps) {
        meterOps.operations().forEach(op -> performOperation(networkId, deviceId, op));
    }

    @Override
    public void performMeterOperation(NetworkId networkId, DeviceId deviceId,
                                      MeterOperation meterOp) {
        performOperation(networkId, deviceId, meterOp);
    }

    private void performOperation(NetworkId networkId, DeviceId deviceId,
                                  MeterOperation op) {

        VirtualMeterOperation vOp = new VirtualMeterOperation(networkId, op);
        pendingOperations.put(idGenerator.getNewId(), vOp);

        switch (op.type()) {
            case ADD:
                //TODO: devirtualize + submit
                break;
            case REMOVE:
                //TODO: devirtualize + withdraw
                break;
            case MODIFY:
                //TODO: devitualize + withdraw and submit
                break;
            default:
                log.warn("Unknown Meter command {}; not sending anything",
                         op.type());
                VirtualMeterProviderService providerService =
                        (VirtualMeterProviderService) providerRegistryService
                                .getProviderService(networkId,
                                                    VirtualMeterProvider.class);
                providerService.meterOperationFailed(op,
                                                     MeterFailReason.UNKNOWN_COMMAND);
        }

    }

    /**
     * De-virtualizes a meter operation.
     * It takes a virtual meter operation, and translate it to a physical meter operation.
     *
     * @param networkId a virtual network identifier
     * @param deviceId a virtual network device identifier
     * @param meterOps a meter operation to be de-virtualized
     * @return de-virtualized meter operation
     */
    private VirtualMeterOperation devirtualize(NetworkId networkId,
                                      DeviceId deviceId,
                                      MeterOperation meterOps) {
        return null;
    }

    /**
     * Virtualizes meter.
     * This translates meter events for virtual networks before delivering them.
     *
     * @param meter
     * @return
     */
    private Meter virtualize(Meter meter) {
        return  null;
    }


    private class InternalMeterListener implements MeterListener {
        @Override
        public void event(MeterEvent event) {
            //TODO: virtualize + notify event to meter provider service
            //Is it enough to enable virtual network provider?
            switch (event.type()) {
                case METER_ADD_REQ:
                    break;
                case METER_REM_REQ:
                    break;
                case METER_ADDED:
                    break;
                case METER_REMOVED:
                    break;
                default:
                    log.warn("Unknown meter event {}", event.type());
            }
        }
    }

    /**
     * A class to hold a network identifier and a meter operation.
     * This class is designed to be used only in virtual network meter provider.
     */
    private final class VirtualMeterOperation {
        private NetworkId networkId;
        private MeterOperation op;

        private VirtualMeterOperation(NetworkId networkId, MeterOperation op) {
            this.networkId = networkId;
            this.op = op;
        }

        private NetworkId networkId() {
            return networkId;
        }

        private MeterOperation operation() {
            return this.op;
        }
    }

    /**
     * A class to hold a network identifier and a meter.
     * This class is designed to be used in only virtual network meter provider.
     */
    private final class VirtualMeter {
        private NetworkId networkId;
        private Meter meter;

        private VirtualMeter(NetworkId networkId, Meter meter) {
            this.networkId = networkId;
            this.meter = meter;
        }

        private NetworkId networkId() {
            return this.networkId;
        }

        private Meter meter() {
            return this.meter;
        }
    }

    /**
     * Id generator for virtual meters to guarantee the uniqueness of its identifier
     * among multiple virtual network meters.
     *
     * @return an ID generator
     */
    private IdGenerator getIdGenerator() {
        return new IdGenerator() {
            private AtomicLong counter = new AtomicLong(0);

            @Override
            public long getNewId() {
                return counter.getAndIncrement();
            }
        };
    }
}
