/*
 * 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.onlab.packet.pim;

import org.onlab.packet.BasePacket;
import org.onlab.packet.Deserializer;
import org.onlab.packet.IPacket;
import org.onlab.packet.IpAddress;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;

import static com.google.common.base.MoreObjects.toStringHelper;
import static org.onlab.packet.PacketUtils.checkInput;

public class PIMHello extends BasePacket {

    private IpAddress nbrIpAddress;
    private boolean priorityPresent = false;

    private Map<Short, PIMHelloOption> options = new HashMap<>();

    /**
     * Create a PIM Hello packet with the most common hello options and default
     * values.  The values of any options can be easily changed by modifying the value of
     * the option with the desired change.
     */
    public void createDefaultOptions() {
        options.put(PIMHelloOption.OPT_HOLDTIME, new PIMHelloOption(PIMHelloOption.OPT_HOLDTIME));
        options.put(PIMHelloOption.OPT_PRIORITY, new PIMHelloOption(PIMHelloOption.OPT_PRIORITY));
        options.put(PIMHelloOption.OPT_GENID, new PIMHelloOption(PIMHelloOption.OPT_GENID));
    }

    /**
     * Add a PIM Hello option to this hello message.  Note
     *
     * @param opt the PIM Hello option we are adding
     */
    public void addOption(PIMHelloOption opt) {
        this.options.put(opt.getOptType(), opt);
    }

    public Map<Short, PIMHelloOption> getOptions() {
        return this.options;
    }

    /**
     * Sets all payloads parent packet if applicable, then serializes this
     * packet and all payloads.
     *
     * @return a byte[] containing this packet and payloads
     */
    @Override
    public byte[] serialize() {
        int totalLen = 0;


         // Since we are likely to only have 3-4 options, go head and walk the
         // hashmap twice, once to calculate the space needed to allocate a
         // buffer, the second time serialize the options into the buffer.  This
         // saves us from allocating an over sized buffer the re-allocating and
         // copying.
        for (Short optType : options.keySet()) {
            PIMHelloOption opt = options.get(optType);
            totalLen += PIMHelloOption.MINIMUM_OPTION_LEN_BYTES + opt.getOptLength();
        }

        byte[] data = new byte[totalLen];
        ByteBuffer bb = ByteBuffer.wrap(data);

        // Now serialize the data.
        for (Short optType : options.keySet()) {
            PIMHelloOption opt = options.get(optType);
            bb.put(opt.serialize());
        }
        return data;
    }

    /**
     * XXX: This is deprecated, DO NOT USE, use the deserializer() function instead.
     */
    public IPacket deserialize(final byte[] data, final int offset,
                               final int length) {
        // TODO: throw an expection?
        return null;
    }

    /**
     * Deserialize this hello message.
     *
     * @return a deserialized hello message
     */
    public static Deserializer<PIMHello> deserializer() {
        return (data, offset, length) -> {
            checkInput(data, offset, length, PIMHelloOption.MINIMUM_OPTION_LEN_BYTES);
            final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);

            PIMHello hello = new PIMHello();
            while (bb.hasRemaining()) {
                PIMHelloOption opt = PIMHelloOption.deserialize(bb);
                hello.addOption(opt);
            }
            return hello;
        };
    }

    @Override
    public String toString() {
        return toStringHelper(getClass())
                .add("nbrIpAddress", nbrIpAddress.toString())
                .add("priorityPresent", Boolean.toString(priorityPresent))
                .toString();
        // TODO: need to handle options
    }
}
