/*
 * Copyright 2016-present 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.lisp.msg.types;

import io.netty.buffer.ByteBuf;
import org.onosproject.lisp.msg.exceptions.LispParseError;
import org.onosproject.lisp.msg.exceptions.LispReaderException;
import org.onosproject.lisp.msg.exceptions.LispWriterException;
import org.onosproject.lisp.msg.types.lcaf.LispLcafAddress;

import java.util.Objects;

import static org.onosproject.lisp.msg.types.AddressFamilyIdentifierEnum.IP4;
import static org.onosproject.lisp.msg.types.AddressFamilyIdentifierEnum.IP6;
import static org.onosproject.lisp.msg.types.AddressFamilyIdentifierEnum.NO_ADDRESS;
import static org.onosproject.lisp.msg.types.AddressFamilyIdentifierEnum.DISTINGUISHED_NAME;
import static org.onosproject.lisp.msg.types.AddressFamilyIdentifierEnum.MAC;
import static org.onosproject.lisp.msg.types.AddressFamilyIdentifierEnum.LCAF;
import static org.onosproject.lisp.msg.types.AddressFamilyIdentifierEnum.AS;

/**
 * LISP Locator address typed by Address Family Identifier (AFI).
 */
public abstract class LispAfiAddress {

    private final AddressFamilyIdentifierEnum afi;

    /**
     * Initializes AFI enumeration value.
     *
     * @param afi address family identifier
     */
    protected LispAfiAddress(AddressFamilyIdentifierEnum afi) {
        this.afi = afi;
    }

    /**
     * Obtains AFI enumeration value.
     *
     * @return AFI enumeration value
     */
    public AddressFamilyIdentifierEnum getAfi() {
        return afi;
    }

    @Override
    public int hashCode() {
        return Objects.hash(afi);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }

        if (obj == null) {
            return false;
        }

        if (getClass() != obj.getClass()) {
            return false;
        }

        LispAfiAddress other = (LispAfiAddress) obj;
        return afi == other.afi;
    }

    /**
     * AFI address reader class.
     */
    public static class AfiAddressReader implements LispAddressReader<LispAfiAddress> {

        @Override
        public LispAfiAddress readFrom(ByteBuf byteBuf)
                                    throws LispParseError, LispReaderException {

            int index = byteBuf.readerIndex();

            // AFI code -> 16 bits
            short afiCode = (short) byteBuf.getUnsignedShort(index);

            // handle no address
            if (afiCode == NO_ADDRESS.getIanaCode()) {
                byteBuf.readUnsignedShort();
                return new LispNoAddress.NoAddressReader().readFrom(byteBuf);
            }

            // handle IPv4 and IPv6 address
            if (afiCode == IP4.getIanaCode() ||
                afiCode == IP6.getIanaCode()) {
                return new LispIpAddress.IpAddressReader().readFrom(byteBuf);
            }

            // handle distinguished name address
            if (afiCode == DISTINGUISHED_NAME.getIanaCode()) {
                return new LispDistinguishedNameAddress.DistinguishedNameAddressReader().readFrom(byteBuf);
            }

            // handle MAC address
            if (afiCode == MAC.getIanaCode()) {
                return new LispMacAddress.MacAddressReader().readFrom(byteBuf);
            }

            // handle LCAF address
            if (afiCode == LCAF.getIanaCode()) {
                return new LispLcafAddress.LcafAddressReader().readFrom(byteBuf);
            }

            // handle autonomous system address
            if (afiCode == AS.getIanaCode()) {
                return new LispAsAddress.AsAddressReader().readFrom(byteBuf);
            }

            return null;
        }
    }

    /**
     * AFI address writer class.
     */
    public static class AfiAddressWriter implements LispAddressWriter<LispAfiAddress> {

        @Override
        public void writeTo(ByteBuf byteBuf, LispAfiAddress address) throws LispWriterException {

            // AFI code
            byteBuf.writeShort(address.getAfi().getIanaCode());

            switch (address.getAfi()) {
                case NO_ADDRESS:
                    new LispNoAddress.NoAddressWriter().writeTo(byteBuf, (LispNoAddress) address);
                    break;
                case IP4:
                    new LispIpAddress.IpAddressWriter().writeTo(byteBuf, (LispIpv4Address) address);
                    break;
                case IP6:
                    new LispIpAddress.IpAddressWriter().writeTo(byteBuf, (LispIpv6Address) address);
                    break;
                case DISTINGUISHED_NAME:
                    new LispDistinguishedNameAddress.DistinguishedNameAddressWriter().writeTo(byteBuf,
                            (LispDistinguishedNameAddress) address);
                    break;
                case MAC:
                    new LispMacAddress.MacAddressWriter().writeTo(byteBuf, (LispMacAddress) address);
                    break;
                case LCAF:
                    new LispLcafAddress.LcafAddressWriter().writeTo(byteBuf, (LispLcafAddress) address);
                    break;
                case AS:
                    new LispAsAddress.AsAddressWriter().writeTo(byteBuf, (LispAsAddress) address);
                    break;
                default: break; // TODO: need log warning message
            }
        }
    }
}
