/*
 * Copyright 2016 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.message.impl;

import com.google.common.collect.BiMap;
import com.google.common.collect.EnumHashBiMap;
import org.onosproject.cpman.ControlMessage;
import org.projectfloodlight.openflow.protocol.OFType;

import static org.projectfloodlight.openflow.protocol.OFType.*;
import static org.onosproject.cpman.ControlMessage.Type.*;

/**
 * Collection of helper methods to convert protocol agnostic control message to
 * messages used in OpenFlow specification.
 */
public final class OpenFlowControlMessageMapper {

    // prohibit instantiation
    private OpenFlowControlMessageMapper() {
    }

    private static final BiMap<OFType, ControlMessage.Type> MESSAGE_TYPE =
            EnumHashBiMap.create(OFType.class);

    static {
        // key is OpenFlow specific OFType
        // value is protocol agnostic ControlMessage.Type
        MESSAGE_TYPE.put(PACKET_IN, INCOMING_PACKET);
        MESSAGE_TYPE.put(PACKET_OUT, OUTGOING_PACKET);
        MESSAGE_TYPE.put(FLOW_MOD, FLOW_MOD_PACKET);
        MESSAGE_TYPE.put(FLOW_REMOVED, FLOW_REMOVED_PACKET);
        MESSAGE_TYPE.put(STATS_REQUEST, REQUEST_PACKET);
        MESSAGE_TYPE.put(STATS_REPLY, REPLY_PACKET);
    }

    /**
     * Looks up the specified input value to the corresponding value with the specified map.
     *
     * @param map   bidirectional mapping
     * @param input input type
     * @param cls   class of output value
     * @param <I>   type of input value
     * @param <O>   type of output value
     * @return the corresponding value stored in the specified map
     */
    private static <I, O> O lookup(BiMap<I, O> map, I input, Class<O> cls) {
        if (!map.containsKey(input)) {
            throw new RuntimeException(
                    String.format("No mapping found for %s when converting to %s",
                            input, cls.getName()));
        }
        return map.get(input);
    }

    /**
     * Looks up the corresponding {@link ControlMessage.Type} instance
     * from the specified OFType value for OpenFlow message type.
     *
     * @param type OpenFlow message type
     * @return protocol agnostic control message type
     */
    public static ControlMessage.Type lookupControlMessageType(OFType type) {
        return lookup(MESSAGE_TYPE, type, ControlMessage.Type.class);
    }

    /**
     * Looks up the corresponding {@link OFType} instance from the specified
     * ControlMetricType value.
     *
     * @param type control message type
     * @return OpenFlow specific message type
     */
    public static OFType lookupOFType(ControlMessage.Type type) {
        return lookup(MESSAGE_TYPE.inverse(), type, OFType.class);
    }
}
