/*
 * 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.pcepio.protocol;

import org.jboss.netty.buffer.ChannelBuffer;
import org.onosproject.pcepio.exceptions.PcepParseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public final class PcepFactories {

    protected static final Logger log = LoggerFactory.getLogger(PcepFactories.class);

    private static final GenericReader GENERIC_READER = new GenericReader();

    public static final byte SHIFT_FLAG = 5;

    private PcepFactories() {
    }

    /*
     * Returns the instance of PCEP Version.
     *
     * @param version
     * @return PCEP version
     */
    public static PcepFactory getFactory(PcepVersion version) {
        switch (version) {
        case PCEP_1:
            // TODO :  to get the pcep version 1 factory
        default:
            throw new IllegalArgumentException("[PcepFactory:]Unknown version: " + version);
        }
    }

    private static class GenericReader implements PcepMessageReader<PcepMessage> {

        @Override
        public PcepMessage readFrom(ChannelBuffer bb) throws PcepParseException {

            if (!bb.readable()) {
                log.debug("Empty message received");
                throw new PcepParseException("Empty message received");
            }

            /*
             * 0                   1                   2                   3
             * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
             * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             * | Ver |  Flags  |                                               |
             * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             *
             * Currently Version 1 is supported
             * Currently no flags are used, it is all ignored
             */

            byte packetVersion = bb.getByte(bb.readerIndex());
            packetVersion = (byte) (packetVersion >> SHIFT_FLAG);
            PcepFactory factory;

            switch (packetVersion) {

            case 1:
                // TODO : get the factory for version 1
                break;
            default:
                throw new IllegalArgumentException("Unknown Packet version: " + packetVersion);
            }
            // TODO : Read the PCEP message from the factory
            return null;
        }
    }

    /*
     * Returns GENERIC_READER.
     *
     * @return GENERIC_READER
     */
    public static PcepMessageReader<PcepMessage> getGenericReader() {
        return GENERIC_READER;
    }
}
