/*
 * 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 com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
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.LispTeRecord.TeRecordWriter;

import java.util.List;
import java.util.Objects;

import static com.google.common.base.MoreObjects.toStringHelper;
import static org.onosproject.lisp.msg.types.LispLcafAddress.COMMON_HEADER_SIZE;

/**
 * Traffic Engineering (TE) type LCAF address class.
 * <p>
 * Traffic Engineering type is defined in draft-ietf-lisp-lcaf-20
 * https://tools.ietf.org/html/draft-ietf-lisp-lcaf-20#page-16
 *
 * <pre>
 * {@literal
 *  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
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |           AFI = 16387         |     Rsvd1     |     Flags     |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |   Type = 10   |     Rsvd2     |            Length             |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |           Rsvd3         |L|P|S|           AFI = x             |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |                         Reencap Hop 1  ...                    |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |           Rsvd3         |L|P|S|           AFI = x             |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |                         Reencap Hop k  ...                    |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * }</pre>
 */
public final class LispTeLcafAddress extends LispLcafAddress {

    private final List<LispTeRecord> records;

    /**
     * Initializes Traffic Engineering type LCAF address.
     *
     * @param records a collection of Re-encapsulated RLOC addresses
     */
    private LispTeLcafAddress(List<LispTeRecord> records) {
        super(LispCanonicalAddressFormatEnum.TRAFFIC_ENGINEERING);
        this.records = records;
    }

    /**
     * Obtains a collection of TE records.
     *
     * @return a collection of TE records
     */
    public List<LispTeRecord> getTeRecords() {
        return ImmutableList.copyOf(records);
    }

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

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

        if (obj instanceof LispTeLcafAddress) {
            final LispTeLcafAddress other = (LispTeLcafAddress) obj;
            return Objects.equals(records, other.records);
        }
        return false;
    }

    @Override
    public String toString() {
        return toStringHelper(this)
                .add("TE records", records).toString();
    }

    public static final class TeAddressBuilder extends LcafAddressBuilder<TeAddressBuilder> {
        private List<LispTeRecord> records;

        /**
         * Sets a collection of TE records.
         *
         * @param records a collection of TE records
         * @return TeAddressBuilder object
         */
        public TeAddressBuilder withTeRecords(List<LispTeRecord> records) {
            this.records = records;
            return this;
        }

        /**
         * Builds LispTeLcafAddress instance.
         *
         * @return LispTeLcafAddress instance
         */
        public LispTeLcafAddress build() {
            return new LispTeLcafAddress(records);
        }
    }
    /**
     * TE LCAF address reader class.
     */
    public static class TeLcafAddressReader implements LispAddressReader<LispTeLcafAddress> {

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

            LispLcafAddress lcafAddress = LispLcafAddress.deserializeCommon(byteBuf);

            List<LispTeRecord> teRecords = Lists.newArrayList();
            while (byteBuf.readerIndex() - COMMON_HEADER_SIZE < lcafAddress.getLength()) {
                teRecords.add(new LispTeRecord.TeRecordReader().readFrom(byteBuf));
            }

            return new TeAddressBuilder()
                        .withTeRecords(teRecords)
                        .build();
        }
    }

    /**
     * TE LCAF address writer class.
     */
    public static class TeLcafAddressWriter implements LispAddressWriter<LispTeLcafAddress> {

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

            int lcafIndex = byteBuf.writerIndex();
            LispLcafAddress.serializeCommon(byteBuf, address);

            TeRecordWriter writer = new TeRecordWriter();

            List<LispTeRecord> teRecords = address.getTeRecords();
            for (int i = 0; i < teRecords.size(); i++) {
                writer.writeTo(byteBuf, teRecords.get(i));
            }

            LispLcafAddress.updateLength(lcafIndex, byteBuf);
        }
    }
}
