/*
 * Copyright 2017-present Open Networking Foundation
 *
 * 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.drivers.lisp.extensions;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Maps;
import org.onlab.util.KryoNamespace;
import org.onosproject.mapping.addresses.ASMappingAddress;
import org.onosproject.mapping.addresses.DNMappingAddress;
import org.onosproject.mapping.addresses.EthMappingAddress;
import org.onosproject.mapping.addresses.ExtensionMappingAddress;
import org.onosproject.mapping.addresses.ExtensionMappingAddressType;
import org.onosproject.mapping.addresses.IPMappingAddress;
import org.onosproject.mapping.addresses.MappingAddress;
import org.onosproject.net.flow.AbstractExtension;
import org.onosproject.store.serializers.KryoNamespaces;

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

import static com.google.common.base.MoreObjects.toStringHelper;
import static org.onosproject.mapping.addresses.ExtensionMappingAddressType
                    .ExtensionMappingAddressTypes.TRAFFIC_ENGINEERING_ADDRESS;

/**
 * Implementation of LISP traffic engineering address.
 * For a given EID lookup into the mapping database, this LCAF can be returned
 * to provide a list of locators in an explicit re-encapsulation path.
 */
public final class LispTeAddress extends AbstractExtension
                                            implements ExtensionMappingAddress {

    private static final String TE_RECORDS = "records";

    private List<TeRecord> records;

    private KryoNamespace appKryo = new KryoNamespace.Builder()
                                            .register(KryoNamespaces.API)
                                            .register(MappingAddress.class)
                                            .register(MappingAddress.Type.class)
                                            .register(IPMappingAddress.class)
                                            .register(ASMappingAddress.class)
                                            .register(DNMappingAddress.class)
                                            .register(EthMappingAddress.class)
                                            .register(TeRecord.class)
                                            .build();

    /**
     * Default constructor.
     */
    public LispTeAddress() {
    }

    /**
     * Creates an instance with initialized parameters.
     *
     * @param records a collection of TE records
     */
    private LispTeAddress(List<TeRecord> records) {
        this.records = records;
    }

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

    @Override
    public ExtensionMappingAddressType type() {
        return TRAFFIC_ENGINEERING_ADDRESS.type();
    }

    @Override
    public byte[] serialize() {
        Map<String, Object> parameterMap = Maps.newHashMap();

        parameterMap.put(TE_RECORDS, records);
        return appKryo.serialize(parameterMap);
    }

    @Override
    public void deserialize(byte[] data) {
        Map<String, Object> parameterMap = appKryo.deserialize(data);

        this.records = (List<TeRecord>) parameterMap.get(TE_RECORDS);
    }

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

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

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

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

    /**
     * A builder for building LispTeAddress.
     */
    public static final class Builder {
        private List<TeRecord> records;

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

        /**
         * Builds LispTeAddress instance.
         *
         * @return LispTeAddress instance
         */
        public LispTeAddress build() {
            return new LispTeAddress(records);
        }
    }

    /**
     * Traffic engineering record class.
     */
    public static final class TeRecord {
        private boolean lookup;
        private boolean rlocProbe;
        private boolean strict;
        private MappingAddress address;

        /**
         *
         *
         * @param lookup     lookup bit
         * @param rlocProbe  rloc probe bit
         * @param strict     strict bit
         * @param address    RTR address
         */
        private TeRecord(boolean lookup, boolean rlocProbe, boolean strict,
                         MappingAddress address) {
            this.lookup = lookup;
            this.rlocProbe = rlocProbe;
            this.strict = strict;
            this.address = address;
        }

        /**
         * Obtains lookup bit flag.
         *
         * @return lookup bit flag
         */
        public boolean isLookup() {
            return lookup;
        }

        /**
         * Obtains RLOC probe bit flag.
         *
         * @return RLOC probe bit flag
         */
        public boolean isRlocProbe() {
            return rlocProbe;
        }

        /**
         * Obtains strict bit flag.
         *
         * @return strict bit flag
         */
        public boolean isStrict() {
            return strict;
        }

        /**
         * Obtains Re-encapsulated RLOC address.
         *
         * @return Re-encapsulated RLOC address
         */
        public MappingAddress getAddress() {
            return address;
        }

        @Override
        public int hashCode() {
            return Objects.hash(lookup, rlocProbe, strict, address);
        }

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

            if (obj instanceof TeRecord) {
                final TeRecord other = (TeRecord) obj;
                return Objects.equals(this.lookup, other.lookup) &&
                        Objects.equals(this.rlocProbe, other.rlocProbe) &&
                        Objects.equals(this.strict, other.strict) &&
                        Objects.equals(this.address, other.address);
            }
            return false;
        }

        @Override
        public String toString() {
            return toStringHelper(this)
                    .add("Lookup bit", lookup)
                    .add("RLOC probe bit", rlocProbe)
                    .add("strict bit", strict)
                    .add("RTR address", address)
                    .toString();
        }

        /**
         * A builder for building TeRecord.
         */
        public static final class Builder {
            private boolean lookup;
            private boolean rlocProbe;
            private boolean strict;
            private MappingAddress address;

            /**
             * Sets lookup flag.
             *
             * @param lookup lookup flag
             * @return Builder object
             */
            public Builder withIsLookup(boolean lookup) {
                this.lookup = lookup;
                return this;
            }

            /**
             * Sets RLOC probe flag.
             *
             * @param rlocProbe RLOC probe flag
             * @return Builder object
             */
            public Builder withIsRlocProbe(boolean rlocProbe) {
                this.rlocProbe = rlocProbe;
                return this;
            }

            /**
             * Sets strict flag.
             *
             * @param strict strict flag
             * @return Builder object
             */
            public Builder withIsStrict(boolean strict) {
                this.strict = strict;
                return this;
            }

            /**
             * Sets RTR RLOC address.
             *
             * @param address RTR RLOC address
             * @return Builder object
             */
            public Builder withRtrRlocAddress(MappingAddress address) {
                this.address = address;
                return this;
            }

            /**
             * Builds TeRecord instance.
             *
             * @return TeRcord instance
             */
            public TeRecord build() {

                return new TeRecord(lookup, rlocProbe, strict, address);
            }
        }
    }
}
