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

import org.onosproject.incubator.net.meter.Band;
import org.onosproject.incubator.net.meter.Meter;
import org.onosproject.incubator.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.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 Integer 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);
        }
        builder.setBands(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(value -> value != null).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");
    }
}
