/*
 * 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.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");
    }
}
