/*
 * Copyright 2015-present 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.of.meter.impl;

import org.onosproject.net.meter.Band;
import org.onosproject.net.meter.Meter;
import org.onosproject.net.meter.MeterId;
import org.projectfloodlight.openflow.protocol.OFFactory;
import org.projectfloodlight.openflow.protocol.OFMeterFlags;
import org.projectfloodlight.openflow.protocol.OFMeterMod;
import org.projectfloodlight.openflow.protocol.OFMeterModCommand;
import org.projectfloodlight.openflow.protocol.meterband.OFMeterBand;
import org.projectfloodlight.openflow.protocol.meterband.OFMeterBandDrop;
import org.projectfloodlight.openflow.protocol.meterband.OFMeterBandDscpRemark;
import org.slf4j.Logger;

import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

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

/**
 * Builder for a meter modification.
 */
public final class MeterModBuilder {

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

    private final long xid;
    private final OFFactory factory;
    private Meter.Unit unit = Meter.Unit.KB_PER_SEC;
    private boolean burst = false;
    private Long id;
    private Collection<Band> bands;

    public MeterModBuilder(long xid, OFFactory factory) {
        this.xid = xid;
        this.factory = factory;
    }

    public static MeterModBuilder builder(long xid, OFFactory factory) {
        return new MeterModBuilder(xid, factory);
    }

    public MeterModBuilder withRateUnit(Meter.Unit unit) {
        this.unit = unit;
        return this;
    }

    public MeterModBuilder burst() {
        this.burst = true;
        return this;
    }

    public MeterModBuilder withId(MeterId meterId) {
        this.id = meterId.id();
        return this;
    }

    public MeterModBuilder withBands(Collection<Band> bands) {
        this.bands = bands;
        return this;
    }

    public OFMeterMod add() {
        validate();
        OFMeterMod.Builder builder = builderMeterMod();
        builder.setCommand(OFMeterModCommand.ADD.ordinal());
        return builder.build();
    }

    public OFMeterMod remove() {
        validate();
        OFMeterMod.Builder builder = builderMeterMod();
        builder.setCommand(OFMeterModCommand.DELETE.ordinal());
        return builder.build();
    }

    public OFMeterMod modify() {
        validate();
        OFMeterMod.Builder builder = builderMeterMod();
        builder.setCommand(OFMeterModCommand.MODIFY.ordinal());
        return builder.build();
    }

    private OFMeterMod.Builder builderMeterMod() {
        OFMeterMod.Builder builder = factory.buildMeterMod();
        int flags = 0;
        if (burst) {
            // covering loxi short comings.
            flags |= 1 << OFMeterFlags.BURST.ordinal();
        }
        switch (unit) {
            case PKTS_PER_SEC:
                flags |= 1 << OFMeterFlags.PKTPS.ordinal();
                break;
            case KB_PER_SEC:
                flags |= 1 << OFMeterFlags.KBPS.ordinal();
                break;
            default:
                log.warn("Unknown unit type {}", unit);
        }
        //FIXME: THIS WILL CHANGE IN OF1.4 to setBands.
        builder.setMeters(buildBands());
        builder.setFlags(flags)
                .setMeterId(id)
                .setXid(xid);
        return builder;
    }

    private List<OFMeterBand> buildBands() {
        return bands.stream().map(b -> {
            switch (b.type()) {
                case DROP:
                    OFMeterBandDrop.Builder dropBuilder =
                            factory.meterBands().buildDrop();
                    if (burst) {
                        dropBuilder.setBurstSize(b.burst());
                    }
                    dropBuilder.setRate(b.rate());
                    return dropBuilder.build();
                case REMARK:
                    OFMeterBandDscpRemark.Builder remarkBand =
                            factory.meterBands().buildDscpRemark();
                    if (burst) {
                        remarkBand.setBurstSize(b.burst());
                    }
                    remarkBand.setRate(b.rate());
                    remarkBand.setPrecLevel(b.dropPrecedence());
                    return remarkBand.build();
                default:
                    log.warn("Unknown band type {}", b.type());
                    return null;
            }
        }).filter(Objects::nonNull).collect(Collectors.toList());
    }

    private void validate() {
        checkNotNull(id, "id cannot be null");
        checkNotNull(bands, "Must have bands");
        checkArgument(bands.size() > 0, "Must have at lease one band");
    }
}
