/*
 * Copyright 2016 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.teyang.utils.topology;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;

import java.util.List;

import org.onosproject.tetopology.management.api.KeyId;
import org.onosproject.tetopology.management.api.TeTopologyEvent;
import org.onosproject.tetopology.management.api.link.NetworkLink;
import org.onosproject.tetopology.management.api.node.NetworkNode;
import org.onosproject.teyang.api.OperationType;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev20151208.IetfNetwork.OnosYangOpType;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev20151208
        .ietfnetwork.DefaultNetworks;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev20151208
        .ietfnetwork.DefaultNetworksState;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev20151208
        .ietfnetwork.NetworkId;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev20151208
        .ietfnetwork.Networks;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev20151208
        .ietfnetwork.NetworksState;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev20151208
        .ietfnetwork.networks.DefaultNetwork;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev20151208
        .ietfnetwork.networks.Network;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev20151208
        .ietfnetwork.networks.Network.NetworkBuilder;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev20151208
        .ietfnetwork.networks.network.DefaultNetworkTypes;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev20151208
        .ietfnetwork.networks.network.DefaultSupportingNetwork;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev20151208.ietfnetwork.networks.network.DefaultSupportingNetwork.SupportingNetworkBuilder;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev20151208
        .ietfnetwork.networks.network.NetworkTypes;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev20151208
        .ietfnetwork.networks.network.Node;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev20151208
        .ietfnetwork.networks.network.SupportingNetwork;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev20151208
        .ietfnetworktopology.networks.network.AugmentedNdNetwork;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev20151208
        .ietfnetworktopology.networks.network.DefaultAugmentedNdNetwork;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev20151208.ietfnetworktopology.networks.network.DefaultAugmentedNdNetwork.AugmentedNdNetworkBuilder;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev20151208
        .ietfnetworktopology.networks.network.augmentedndnetwork.Link;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
        .ietftetopology.networks.network.AugmentedNwNetwork;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
        .ietftetopology.networks.network.DefaultAugmentedNwNetwork;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
        .ietftetopology.networks.network.networktypes.AugmentedNwNetworkTypes;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
        .ietftetopology.networks.network.networktypes.DefaultAugmentedNwNetworkTypes;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708.ietftetopology.tetopologyaugment.DefaultTe;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708.ietftetopology.tetopologyaugment.Te;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708.ietftetopology.tetopologytype.DefaultTeTopology;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708.ietftetopology.tetopologytype.TeTopology;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708.ietftetopology.IetfTeTopologyEvent;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705
        .ietftetypes.TeGlobalId;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705
        .ietftetypes.TeTopologyId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.Lists;


/**
 * Networks, Networks State conversion functions.
 */
public final class NetworkConverter {
    private static final String
        E_NULL_TE_NETWORKS = "TeSubsystem networks cannot be null";
    private static final String
        E_NULL_TE_NETWORK_LIST = "TeSubsystem network list cannot be null";
    private static final String
        E_NULL_TE_NETWORK = "TeSubsystem network cannot be null";
    private static final String
        E_NULL_TE_NETWORKID = "TeSubsystem networkId cannot be null";
    private static final String
        E_NULL_YANG_NETWORKS = "YANG networks cannot be null";
    private static final String
        E_NULL_YANG_NETWORK_LIST = "YANG network list cannot be null";
    private static final String
        E_NULL_YANG_NETWORK = "YANG network cannot be null";
    private static final String
        E_NULL_YANG_NETWORKID = "YANG networkId cannot be null";
    private static final String
        E_NULL_YANG_NETWORKSSTATE = "YANG networksState cannot be null";
    private static final String
        E_DIFF_YANG_NETWORKID = "YANG networkId must be same in Network and NetworkState";
    private static final String
        E_NULL_YANG_NETWORKSSTATE_NETWORK = "YANG networksState network cannot be null";
    private static final String
        E_NULL_YANG_NETWORKSSTATE_NETWORKREF = "YANG networksState networkRef cannot be null";

    private static final Logger log = LoggerFactory.getLogger(NetworkConverter.class);

    // no instantiation
    private NetworkConverter() {
    }

    private static OnosYangOpType toNetworksOperationType(OperationType operation) {
        switch (operation) {
        case CREATE:
            return OnosYangOpType.CREATE;

        case DELETE:
            return OnosYangOpType.DELETE;

        case REMOVE:
            return OnosYangOpType.REMOVE;

        case MERGE:
            return OnosYangOpType.MERGE;

        case REPLACE:
            return OnosYangOpType.REPLACE;

        default:
            return OnosYangOpType.NONE;
        }
    }

    /**
     * Networks object conversion from TE Topology subsystem to YANG.
     *
     * @param teSubsystem TE Topology subsystem networks object
     * @param operation operation type
     * @return Networks YANG object
     */
    public static Networks teSubsystem2YangNetworks(
            org.onosproject.tetopology.management.api.Networks teSubsystem,
            OperationType operation) {
        checkNotNull(teSubsystem, E_NULL_TE_NETWORKS);
        checkNotNull(teSubsystem.networks(), E_NULL_TE_NETWORK_LIST);
        Networks.NetworksBuilder builder =
                DefaultNetworks.builder()
                        .yangNetworksOpType(toNetworksOperationType(operation));
        List<Network> networks = Lists.newArrayList();
        for (org.onosproject.tetopology.management.api.Network teNetwork : teSubsystem.networks()) {
            networks.add(teSubsystem2YangNetwork(teNetwork, operation));
        }
        builder.network(networks);
        return builder.build();
    }

    /**
     * Network States object conversion from TE Topology subsystem to YANG.
     *
     * @param teSubsystem TE Topology subsystem networks object
     * @param operation operation type
     * @return NetworkStates YANG object
     */
    public static NetworksState teSubsystem2YangNetworkStates(
            org.onosproject.tetopology.management.api.Networks teSubsystem,
            OperationType operation) {
        checkNotNull(teSubsystem, "teSubsystem object cannot be null");
        checkNotNull(teSubsystem.networks(), "TeSubsystem Networks object cannot be null");
        NetworksState.NetworksStateBuilder builder =
                DefaultNetworksState.builder()
                        .yangNetworksStateOpType(toNetworksOperationType(operation));
        List<org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev20151208
                .ietfnetwork.networksstate.Network> networks = Lists.newArrayList();
        for (org.onosproject.tetopology.management.api.Network teNetwork : teSubsystem.networks()) {
            networks.add(teSubsystem2YangNetworkState(teNetwork, operation));
        }
        builder.network(networks);
        return builder.build();
    }

    private static org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev20151208
            .ietfnetwork.networksstate.Network networkStateNetwork(Network network,
                                                                   NetworksState yangNetworkStates) {
        checkNotNull(network, "YANG Network object cannot be null");
        checkNotNull(yangNetworkStates, "YANG NetworksState object cannot be null");
        if (yangNetworkStates.network() == null) {
            return null;
        }

        for (org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev20151208
                .ietfnetwork.networksstate.Network stateNetwork : yangNetworkStates.network()) {
            if (stateNetwork.networkRef().equals(network.networkId())) {
                return stateNetwork;
            }
        }
        return null;
    }

    /**
     * Networks object conversion from YANG to TE Topology subsystem.
     *
     * @param yangNetworks Networks YANG object
     * @param yangNetworkStates NetworkStates YANG object
     * @return teSubsystem TE Topology subsystem networks object
     */
    public static org.onosproject.tetopology.management.api.Networks yang2TeSubsystemNetworks(
            Networks yangNetworks, NetworksState yangNetworkStates) {
        checkNotNull(yangNetworks, E_NULL_YANG_NETWORKS);
        checkNotNull(yangNetworks.network(), E_NULL_YANG_NETWORK_LIST);
        checkNotNull(yangNetworkStates, E_NULL_YANG_NETWORKSSTATE);

        org.onosproject.tetopology.management.api.DefaultNetworks defaultNetworks =
                new org.onosproject.tetopology.management.api.DefaultNetworks();
        List<org.onosproject.tetopology.management.api.Network> networks = Lists.newArrayList();
        for (Network network : yangNetworks.network()) {
            org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev20151208
                    .ietfnetwork.networksstate.Network stateNetwork =
                            networkStateNetwork(network, yangNetworkStates);
            org.onosproject.tetopology.management.api.Network teNetwork;
            if (stateNetwork == null) {
                log.info("networkId {} can't be found in yangNetworkStates",
                          network.networkId());
                teNetwork = yang2TeSubsystemNetwork(network);
            } else {
                teNetwork = yang2TeSubsystemNetwork(network, stateNetwork);
            }
            networks.add(teNetwork);
        }

        defaultNetworks.setNetworks(networks);
        return defaultNetworks;
    }

    private static NetworkBuilder te2YangSupportingNetwork(NetworkBuilder builder,
                                                           List<KeyId> teSpptNetworkIds) {
        List<SupportingNetwork> snws = Lists.newArrayList();
        SupportingNetworkBuilder spNetworkBuilder = DefaultSupportingNetwork.builder();
        for (KeyId teSpNwKey : teSpptNetworkIds) {
            snws.add(spNetworkBuilder
                    .networkRef(NetworkId.fromString(teSpNwKey.toString()))
                    .build());
        }
        return builder.supportingNetwork(snws);
    }

    private static NetworkBuilder te2YangNodes(NetworkBuilder builder,
                                               List<NetworkNode> teNodes) {
        List<Node> nodeList = Lists.newArrayList();
        // Add each node
        for (org.onosproject.tetopology.management.api.node.NetworkNode node : teNodes) {
            // Convert the te node to a YO.
            nodeList.add(NodeConverter.teSubsystem2YangNode(node));
        }
        return builder.node(nodeList);
    }

    private static NetworkBuilder te2YangLinks(NetworkBuilder builder,
                                               List<NetworkLink> teLinks) {
        List<Link> linkList = Lists.newArrayList();
        // Add each link
        for (org.onosproject.tetopology.management.api.link.NetworkLink link : teLinks) {
            // Convert the te link to a YO
            linkList.add(LinkConverter.teSubsystem2YangLink(link));
        }
        AugmentedNdNetworkBuilder ndAugment = DefaultAugmentedNdNetwork.builder();
        ndAugment.link(linkList);
        builder.addYangAugmentedInfo(ndAugment.build(), AugmentedNdNetwork.class);
        return builder;
    }

    private static NetworkBuilder te2YangNetworkType(NetworkBuilder builder,
                org.onosproject.tetopology.management.api.TeTopologyId teTopologyId) {
        NetworkTypes.NetworkTypesBuilder nwType = DefaultNetworkTypes.builder();
        if (teTopologyId != null) {
            // Set "te-topology" network type.
            TeTopology.TeTopologyBuilder teTopology = DefaultTeTopology.builder();
            AugmentedNwNetworkTypes.AugmentedNwNetworkTypesBuilder teNwType =
                    DefaultAugmentedNwNetworkTypes.builder();
            teNwType.teTopology(teTopology.build());
            nwType.addYangAugmentedInfo(teNwType.build(), AugmentedNwNetworkTypes.class);
        }
        return builder.networkTypes(nwType.build());
    }

    private static NetworkBuilder te2YangTopologyIds(NetworkBuilder builder,
            org.onosproject.tetopology.management.api.TeTopologyId teTopologyId) {
        Te.TeBuilder teBuilder = DefaultTe.builder();
        teBuilder.clientId(new TeGlobalId(teTopologyId.clientId()));
        teBuilder.providerId(new TeGlobalId(teTopologyId.providerId()));
        if (teTopologyId.topologyId() !=  null) {
            teBuilder.teTopologyId(new TeTopologyId(teTopologyId.topologyId()));
        }

        AugmentedNwNetwork.AugmentedNwNetworkBuilder nwAugment = DefaultAugmentedNwNetwork
                .builder();
        nwAugment.te(teBuilder.build());
        builder.addYangAugmentedInfo(nwAugment.build(),
                                            AugmentedNwNetwork.class);
        return builder;
    }

    /**
     * Network object conversion from TE Topology subsystem to YANG.
     *
     * @param teSubsystem TE Topology subsystem network object
     * @param operation operation type
     * @return Network YANG object
     */
    public static Network teSubsystem2YangNetwork(
            org.onosproject.tetopology.management.api.Network teSubsystem,
            OperationType operation) {
        checkNotNull(teSubsystem, E_NULL_TE_NETWORK);
        checkNotNull(teSubsystem.networkId(), E_NULL_TE_NETWORKID);

        // Generate a network builder with the specific networkId.
        NetworkId networkId = NetworkId.fromString(teSubsystem.networkId().toString());
        NetworkBuilder builder = DefaultNetwork.builder()
                                               .yangNetworkOpType(
                                                       toNetworksOperationType(operation))
                                               .networkId(networkId);

        // Supporting networks
        if (teSubsystem.getSupportingNetworkIds() != null) {
            builder = te2YangSupportingNetwork(builder, teSubsystem.getSupportingNetworkIds());
        }

        // Nodes
        if (teSubsystem.getNodes() != null) {
            builder = te2YangNodes(builder, teSubsystem.getNodes());
        }

        // Network types
        builder = te2YangNetworkType(builder, teSubsystem.getTeTopologyId());

        // Add links - link is the augmentation
        if (teSubsystem.getLinks() != null) {
            builder = te2YangLinks(builder, teSubsystem.getLinks());
        }

        // TE Topology IDs
        if (teSubsystem.getTeTopologyId() != null) {
            builder = te2YangTopologyIds(builder, teSubsystem.getTeTopologyId());
        }

        return builder.build();
    }

    /**
     * Network State object conversion from TE Topology subsystem to YANG.
     *
     * @param teSubsystem TE Topology subsystem network object
     * @param operation operation type
     * @return Network YANG object
     */
    public static org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network
                        .rev20151208.ietfnetwork.networksstate.Network
            teSubsystem2YangNetworkState(
                    org.onosproject.tetopology.management.api.Network teSubsystem,
                    OperationType operation) {
        checkNotNull(teSubsystem, E_NULL_TE_NETWORK);
        checkNotNull(teSubsystem.networkId(), E_NULL_TE_NETWORKID);

        org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev20151208
                .ietfnetwork.networksstate.Network.NetworkBuilder stateBuilder =
        org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev20151208
                .ietfnetwork.networksstate.DefaultNetwork.builder();

        if (teSubsystem.networkId() != null) {
            stateBuilder.networkRef(NetworkId.fromString(teSubsystem.networkId().toString()));
        }
        stateBuilder.serverProvided(teSubsystem.isServerProvided());

        // Operation type may be required.
        return stateBuilder.build();
    }


    /**
     * Network conversion from YANG to TE Topology subsystem.
     *
     * @param yangNetwork Network YANG object
     * @return TE Topology subsystem defaultNetwork object
     */
    private static org.onosproject.tetopology.management.api.DefaultNetwork yang2TeDefaultNetwork(
            Network yangNetwork) {
        checkNotNull(yangNetwork, E_NULL_YANG_NETWORK);
        checkNotNull(yangNetwork.networkId(), E_NULL_YANG_NETWORKID);
        String networkId = yangNetwork.networkId().uri().string();
        org.onosproject.tetopology.management.api.DefaultNetwork teNetwork =
                new org.onosproject.tetopology.management.api.DefaultNetwork(KeyId.keyId(networkId));

        // Supporting networks
        if (yangNetwork.supportingNetwork() != null) {
            List<KeyId> supportingNetworkIds = Lists.newArrayList();
            for (SupportingNetwork supportNw : yangNetwork.supportingNetwork()) {
                supportingNetworkIds.add(
                        KeyId.keyId(supportNw.networkRef().uri().string()));
            }
            teNetwork.setSupportingNetworkIds(supportingNetworkIds);
        }

        // Nodes
        if (yangNetwork.node() != null) {
            List<org.onosproject.tetopology.management.api.node.NetworkNode>
                teNodes = Lists.newArrayList();
            for (Node node : yangNetwork.node()) {
                // Convert the Yang Node to a TE node.
                teNodes.add(NodeConverter.yang2TeSubsystemNode(node, yangNetwork.networkId()));
            }
            teNetwork.setNodes(teNodes);
        }

        // Links
        if (yangNetwork.yangAugmentedInfo(AugmentedNdNetwork.class) != null) {
            AugmentedNdNetwork augmentLink =
                    (AugmentedNdNetwork) yangNetwork.yangAugmentedInfo(AugmentedNdNetwork.class);
            List<org.onosproject.tetopology.management.api.link.NetworkLink>
                teLinks = Lists.newArrayList();
            for (Link link : augmentLink.link()) {
                // Convert the Yang Link to a TE link.
                teLinks.add(LinkConverter.yang2TeSubsystemLink(link, yangNetwork.networkId()));
            }
            teNetwork.setLinks(teLinks);
        }

        // TE Topology Ids
        if (yangNetwork.yangAugmentedInfo(AugmentedNwNetwork.class) != null) {
            AugmentedNwNetwork augmentTeIds =
                    (AugmentedNwNetwork) yangNetwork.yangAugmentedInfo(AugmentedNwNetwork.class);
            org.onosproject.tetopology.management.api.TeTopologyId teTopologyId =
                    new org.onosproject.tetopology.management.api.TeTopologyId(
                            augmentTeIds.te().clientId().uint32(),
                            augmentTeIds.te().providerId().uint32(),
                            augmentTeIds.te().teTopologyId().string());

            teNetwork.setTeTopologyId(teTopologyId);
        }

        return teNetwork;
    }

    /**
     * Network object conversion from YANG to TE Topology subsystem.
     *
     * @param yangNetwork Network YANG object
     * @return network TE Topology subsystem networks object
     */
    public static org.onosproject.tetopology.management.api.Network yang2TeSubsystemNetwork(Network yangNetwork) {
       return yang2TeDefaultNetwork(yangNetwork);
    }

    /**
     * Network and State object conversion from YANG to TE Topology subsystem.
     *
     * @param yangNetwork Network YANG object
     * @param yangNetworkState NetworkState YANG object
     * @return teSubsystem TE Topology subsystem networks object
     */
    public static org.onosproject.tetopology.management.api.Network yang2TeSubsystemNetwork(Network yangNetwork,
            org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev20151208.ietfnetwork
                    .networksstate.Network yangNetworkState) {
        org.onosproject.tetopology.management.api.DefaultNetwork teNetwork =
                yang2TeDefaultNetwork(yangNetwork);

        checkNotNull(yangNetworkState, E_NULL_YANG_NETWORKSSTATE_NETWORK);
        checkNotNull(yangNetworkState.networkRef(), E_NULL_YANG_NETWORKSSTATE_NETWORKREF);
        String networkref = yangNetworkState.networkRef().toString();
        checkState(teNetwork.networkId().toString().equals(networkref),
                   E_DIFF_YANG_NETWORKID);

        teNetwork.setServerProvided(yangNetworkState.serverProvided());

        return teNetwork;
    }

    /**
     * Converts a TE Topology event from the data format used in core to its
     * corresponding YANG Object (YO) format.
     *
     * @param event TE Topology event from the core
     * @return YANG Object converted from event
     */
    public static IetfTeTopologyEvent teTopoEvent2YangIetfTeTopoEvent(TeTopologyEvent event) {
      // TODO: implementation will be submitted as a seperate review.
      return null;
    }
}


