/*
 * 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.bgp.controller;

import static com.google.common.base.Preconditions.checkArgument;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
import java.util.ListIterator;

import org.onosproject.bgpio.protocol.linkstate.BgpLinkLsNlriVer4;
import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4;
import org.onosproject.bgpio.protocol.linkstate.NodeDescriptors;
import org.onosproject.bgpio.types.AutonomousSystemTlv;
import org.onosproject.bgpio.types.BgpLSIdentifierTlv;
import org.onosproject.bgpio.types.BgpValueType;
import org.onosproject.bgpio.types.IsIsNonPseudonode;
import org.onosproject.bgpio.types.IsIsPseudonode;
import org.onosproject.bgpio.types.OspfNonPseudonode;
import org.onosproject.bgpio.types.OspfPseudonode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * The class representing a network bgp device id.
 */
public final class BgpDpid {
    private static final Logger log = LoggerFactory.getLogger(BgpDpid.class);

    private static final String SCHEME = "bgp";
    private static final long UNKNOWN = 0;
    private StringBuilder stringBuilder;
    public static final int NODE_DESCRIPTOR_LOCAL = 1;
    public static final int NODE_DESCRIPTOR_REMOTE = 2;

    /**
     * Initialize BGP id to generate URI.
     *
     * @param linkNlri node NLRI.
     * @param nodeDescriptorType node descriptor type, local/remote
     */
    public BgpDpid(final BgpLinkLsNlriVer4 linkNlri, int nodeDescriptorType) {
        this.stringBuilder = new StringBuilder("");

        if (linkNlri.getRouteDistinguisher() != null) {
            this.stringBuilder.append("RD=").append(linkNlri.getRouteDistinguisher()
                                            .getRouteDistinguisher()).append(":");
        }
        this.stringBuilder.append(":ROUTINGUNIVERSE=").append(((BgpLinkLsNlriVer4) linkNlri).getIdentifier());

        if (nodeDescriptorType == NODE_DESCRIPTOR_LOCAL) {
            add(linkNlri.localNodeDescriptors());
        } else if (nodeDescriptorType == NODE_DESCRIPTOR_REMOTE) {
            add(linkNlri.remoteNodeDescriptors());
        }
    }

    /*
     * Get iso node ID in specified string format.
     */
    private String isoNodeIdString(byte[] isoNodeId) {
        if (isoNodeId != null) {
            return String.format("%02x%02x.%02x%02x.%02x%02x", isoNodeId[0], isoNodeId[1],
                                 isoNodeId[2], isoNodeId[3],
                                 isoNodeId[4], isoNodeId[5]);
        }
        return null;
    }

    /**
     * Initialize BGP id to generate URI.
     *
     * @param nlri node NLRI.
     */
    public BgpDpid(final BgpNodeLSNlriVer4 nlri) {
        this.stringBuilder = new StringBuilder("");
        if (((BgpNodeLSNlriVer4) nlri).getRouteDistinguisher() != null) {
            this.stringBuilder.append("RD=")
                    .append(((BgpNodeLSNlriVer4) nlri).getRouteDistinguisher().getRouteDistinguisher()).append(":");
        }

        this.stringBuilder.append(":ROUTINGUNIVERSE=").append(((BgpNodeLSNlriVer4) nlri).getIdentifier());
        add(((BgpNodeLSNlriVer4) nlri).getLocalNodeDescriptors().getNodedescriptors());
        log.info("BgpDpid :: add");
    }

    /**
     * Obtains instance of this class by appending stringBuilder with node descriptor value.
     *
     * @param value node descriptor
     * @return instance of this class
     */
    public BgpDpid add(final NodeDescriptors value) {
        log.info("BgpDpid :: add function");
        if (value != null) {
            List<BgpValueType> subTlvs = value.getSubTlvs();
            ListIterator<BgpValueType> listIterator = subTlvs.listIterator();
            while (listIterator.hasNext()) {
                BgpValueType tlv = listIterator.next();
                if (tlv.getType() == AutonomousSystemTlv.TYPE) {
                    this.stringBuilder.append(":ASN=").append(((AutonomousSystemTlv) tlv).getAsNum());
                } else if (tlv.getType() == BgpLSIdentifierTlv.TYPE) {
                    this.stringBuilder.append(":DOMAINID=").append(((BgpLSIdentifierTlv) tlv).getBgpLsIdentifier());
                } else if (tlv.getType() == NodeDescriptors.IGP_ROUTERID_TYPE) {
                    if (tlv instanceof IsIsNonPseudonode) {
                        this.stringBuilder.append(":ISOID=").append(
                                isoNodeIdString(((IsIsNonPseudonode) tlv).getIsoNodeId()));
                    } else if (tlv instanceof IsIsPseudonode) {
                        IsIsPseudonode isisPseudonode = ((IsIsPseudonode) tlv);
                        this.stringBuilder.append(":ISOID=").append(
                                isoNodeIdString(((IsIsPseudonode) tlv).getIsoNodeId()));
                        this.stringBuilder.append(":PSN=").append(isisPseudonode.getPsnIdentifier());
                    } else if (tlv instanceof OspfNonPseudonode) {
                        this.stringBuilder.append(":RID=").append(((OspfNonPseudonode) tlv).getrouterID());
                    } else if (tlv instanceof OspfPseudonode) {
                        this.stringBuilder.append(":RID=").append(((OspfPseudonode) tlv).getrouterID());
                    }
                }
            }
        }
        return this;
    }

    @Override
    public String toString() {
        return this.stringBuilder.toString();
    }

    /**
     * Produces bgp URI.
     *
     * @param value string to get URI
     * @return bgp URI, otherwise null
     */
    public static URI uri(String value) {
        try {
            return new URI(SCHEME, value, null);
        } catch (URISyntaxException e) {
            log.info("Exception BgpId URI: " + e.toString());
        }
        return null;
    }

    /**
     * Returns bgpDpid created from the given device URI.
     *
     * @param uri device URI
     * @return object of BgpDpid
     */
    public static BgpDpid bgpDpid(URI uri) {
        checkArgument(uri.getScheme().equals(SCHEME), "Unsupported URI scheme");

        // TODO: return BgpDpid generated from uri
        return null;
    }
}
