/*
 * 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.drivers.p4runtime;

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.Sets;
import org.onosproject.drivers.p4runtime.mirror.P4RuntimeMeterMirror;
import org.onosproject.net.DeviceId;
import org.onosproject.net.meter.Band;
import org.onosproject.net.meter.DefaultBand;
import org.onosproject.net.meter.DefaultMeter;
import org.onosproject.net.meter.DefaultMeterFeatures;
import org.onosproject.net.meter.Meter;
import org.onosproject.net.meter.MeterFeatures;
import org.onosproject.net.meter.MeterOperation;
import org.onosproject.net.meter.MeterProgrammable;
import org.onosproject.net.meter.MeterScope;
import org.onosproject.net.meter.MeterState;
import org.onosproject.net.pi.model.PiMeterId;
import org.onosproject.net.pi.model.PiMeterModel;
import org.onosproject.net.pi.model.PiPipelineModel;
import org.onosproject.net.pi.runtime.PiMeterCellConfig;
import org.onosproject.net.pi.runtime.PiMeterCellHandle;
import org.onosproject.net.pi.runtime.PiMeterCellId;
import org.onosproject.net.pi.service.PiMeterTranslator;
import org.onosproject.net.pi.service.PiTranslationException;

import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.net.meter.MeterOperation.Type.ADD;
import static org.onosproject.net.meter.MeterOperation.Type.MODIFY;
import static org.onosproject.net.meter.MeterOperation.Type.REMOVE;

/**
 * Implementation of MeterProgrammable behaviour for P4Runtime.
 */
public class P4RuntimeMeterProgrammable extends AbstractP4RuntimeHandlerBehaviour implements MeterProgrammable {

    private static final int METER_LOCK_EXPIRE_TIME_IN_MIN = 10;
    private static final LoadingCache<PiMeterCellHandle, Lock>
            ENTRY_LOCKS = CacheBuilder.newBuilder()
            .expireAfterAccess(METER_LOCK_EXPIRE_TIME_IN_MIN, TimeUnit.MINUTES)
            .build(new CacheLoader<PiMeterCellHandle, Lock>() {
                @Override
                public Lock load(PiMeterCellHandle handle) {
                    return new ReentrantLock();
                }
            });

    private PiMeterTranslator translator;
    private P4RuntimeMeterMirror meterMirror;
    private PiPipelineModel pipelineModel;

    @Override
    protected boolean setupBehaviour(String opName) {
        if (!super.setupBehaviour(opName)) {
            return false;
        }

        translator = translationService.meterTranslator();
        meterMirror = handler().get(P4RuntimeMeterMirror.class);
        pipelineModel = pipeconf.pipelineModel();
        return true;
    }

    @Override
    public CompletableFuture<Boolean> performMeterOperation(MeterOperation meterOp) {

        if (!setupBehaviour("performMeterOperation()")) {
            return CompletableFuture.completedFuture(false);
        }

        return CompletableFuture.completedFuture(processMeterOp(meterOp));
    }

    private boolean processMeterOp(MeterOperation meterOp) {
        PiMeterCellConfig piMeterCellConfig;
        switch (meterOp.type()) {
            case ADD:
            case MODIFY:
                // Create a config for modify operation
                try {
                    piMeterCellConfig = translator.translate(meterOp.meter(), pipeconf);
                } catch (PiTranslationException e) {
                    log.warn("Unable translate meter, aborting meter operation {}: {}", meterOp.type(), e.getMessage());
                    log.debug("exception", e);
                    return false;
                }
                break;
            case REMOVE:
                // Create a empty config for reset operation
                PiMeterCellId piMeterCellId = (PiMeterCellId) meterOp.meter().meterCellId();
                piMeterCellConfig = PiMeterCellConfig.reset(piMeterCellId);
                break;
            default:
                log.warn("Meter Operation type {} not supported", meterOp.type());
                return false;
        }

        final PiMeterCellHandle handle = PiMeterCellHandle.of(deviceId, piMeterCellConfig);
        ENTRY_LOCKS.getUnchecked(handle).lock();
        final boolean result = client.write(p4DeviceId, pipeconf)
                .modify(piMeterCellConfig).submitSync().isSuccess();
        if (result) {
            meterMirror.put(handle, piMeterCellConfig);
        }
        ENTRY_LOCKS.getUnchecked(handle).unlock();

        return result;
    }

    @Override
    public CompletableFuture<Collection<Meter>> getMeters() {

        if (!setupBehaviour("getMeters()")) {
            return CompletableFuture.completedFuture(Collections.emptyList());
        }

        Collection<PiMeterCellConfig> piMeterCellConfigs;

        Set<PiMeterId> meterIds = new HashSet<>();
        for (PiMeterModel mode : pipelineModel.meters()) {
            meterIds.add(mode.id());
        }

        piMeterCellConfigs = client.read(p4DeviceId, pipeconf)
                .meterCells(meterIds).submitSync().all(PiMeterCellConfig.class);

        Collection<Meter> meters = piMeterCellConfigs.stream()
                .map(p -> {
                    DefaultMeter meter = (DefaultMeter) DefaultMeter.builder()
                            .withBands(p.meterBands().stream().map(b -> DefaultBand.builder()
                                    .withRate(b.rate())
                                    .burstSize(b.burst())
                                    .ofType(Band.Type.NONE)
                                    .build()).collect(Collectors.toList()))
                            .withCellId(p.cellId()).build();
                    meter.setState(MeterState.ADDED);
                    return meter;
                })
                .collect(Collectors.toList());

        return CompletableFuture.completedFuture(meters);
    }

    @Override
    public CompletableFuture<Collection<MeterFeatures>> getMeterFeatures() {

        if (!setupBehaviour("getMeterFeatures()")) {
            return CompletableFuture.completedFuture(Collections.emptyList());
        }

        Collection<MeterFeatures> meterFeatures = new HashSet<>();
        pipeconf.pipelineModel().meters().forEach(
            m -> meterFeatures.add(new P4RuntimeMeterFeaturesBuilder(m, deviceId).build()));

        return CompletableFuture.completedFuture(meterFeatures);
    }

    /**
     * P4 meter features builder.
     */
    public class P4RuntimeMeterFeaturesBuilder {
        private final PiMeterModel piMeterModel;
        private DeviceId deviceId;

        private static final long PI_METER_START_INDEX = 0L;
        private static final short PI_METER_MAX_BAND = 2;
        private static final short PI_METER_MAX_COLOR = 3;

        public P4RuntimeMeterFeaturesBuilder(PiMeterModel piMeterModel, DeviceId deviceId) {
            this.piMeterModel = checkNotNull(piMeterModel);
            this.deviceId = deviceId;
        }

        /**
         * To build a MeterFeatures using the PiMeterModel object
         * retrieved from pipeconf.
         *
         * @return the meter features object
         */
        public MeterFeatures build() {
            /*
             * We set the basic values before to extract the other information.
             */
            MeterFeatures.Builder builder = DefaultMeterFeatures.builder()
                    .forDevice(deviceId)
                    // The scope value will be PiMeterId
                    .withScope(MeterScope.of(piMeterModel.id().id()))
                    .withMaxBands(PI_METER_MAX_BAND)
                    .withMaxColors(PI_METER_MAX_COLOR)
                    .withStartIndex(PI_METER_START_INDEX)
                    .withEndIndex(piMeterModel.size() - 1);
            /*
             * Pi meter only support NONE type
             */
            Set<Band.Type> bands = Sets.newHashSet();
            bands.add(Band.Type.NONE);
            builder.withBandTypes(bands);
            /*
             * We extract the supported units;
             */
            Set<Meter.Unit> units = Sets.newHashSet();
            if (piMeterModel.unit() == PiMeterModel.Unit.BYTES) {
                units.add(Meter.Unit.KB_PER_SEC);
            } else if (piMeterModel.unit() == PiMeterModel.Unit.PACKETS) {
                units.add(Meter.Unit.PKTS_PER_SEC);
            }
            builder.withUnits(units);
            /*
             * Burst is supported ?
             */
            builder.hasBurst(true);
            /*
             * Stats are supported ?
             */
            builder.hasStats(false);

            return builder.build();
        }

        /**
         * To build an empty meter features.
         * @param deviceId the device id
         * @return the meter features
         */
        public MeterFeatures noMeterFeatures(DeviceId deviceId) {
            return DefaultMeterFeatures.noMeterFeatures(deviceId);
        }
    }
}
