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

import com.google.common.collect.Lists;
import org.onosproject.tetopology.management.api.TeTopologyKey;
import org.onosproject.tetopology.management.api.node.TeNodeKey;
import org.onosproject.tetopology.management.api.node.TtpKey;
import org.onosproject.tetunnel.api.tunnel.DefaultTeTunnel;
import org.onosproject.tetunnel.api.tunnel.TeTunnel;
import org.onosproject.tetunnel.api.tunnel.TeTunnelKey;
import org.onosproject.tetunnel.api.tunnel.path.DefaultTePath;
import org.onosproject.tetunnel.api.tunnel.path.DefaultTeRouteUnnumberedLink;
import org.onosproject.tetunnel.api.tunnel.path.TePath;
import org.onosproject.tetunnel.api.tunnel.path.TeRouteSubobject;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.IetfTe;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.IetfTeOpParam;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.DefaultTe;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.Te;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.pathparamsconfig.Type;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.pathparamsconfig.type
        .DefaultDynamic;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.pathparamsconfig.type
        .DefaultExplicit;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.pathparamsconfig.type
        .explicit.DefaultExplicitRouteObjects;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.pathparamsconfig.type
        .explicit.ExplicitRouteObjects;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.tunnelproperties.Config;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.tunnelproperties
        .DefaultPrimaryPaths;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.tunnelproperties.DefaultState;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.tunnelproperties.PrimaryPaths;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.tunnelproperties.State;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.tunnelsgrouping
        .DefaultTunnels;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.tunnelsgrouping.Tunnels;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.tunnelsgrouping.tunnels
        .DefaultTunnel;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.tunnelsgrouping.tunnels
        .Tunnel;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.LspProt1Forn;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.LspProtBidir1To1;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.LspProtReroute;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes
        .LspProtRerouteExtra;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.LspProtType;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.LspProtUnidir1To1;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.LspProtUnprotected;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes
        .PathSignalingRsvpte;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.PathSignalingSr;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.RouteIncludeEro;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.StateDown;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.StateUp;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.TunnelP2Mp;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.TunnelP2p;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.TunnelType;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes
        .explicitroutesubobject.type.DefaultUnnumberedLink;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes
        .explicitroutesubobject.type.UnnumberedLink;
import org.slf4j.Logger;

import java.util.ArrayList;
import java.util.List;

import static org.onosproject.tetunnel.api.tunnel.TeTunnel.LspProtectionType;
import static org.onosproject.tetunnel.api.tunnel.path.TeRouteSubobject.Type.UNNUMBERED_LINK;
import static org.onosproject.teyang.utils.tunnel.BasicConverter.bytesToLong;
import static org.onosproject.teyang.utils.tunnel.BasicConverter.ipToLong;
import static org.onosproject.teyang.utils.tunnel.BasicConverter.longToByte;
import static org.onosproject.teyang.utils.tunnel.BasicConverter.longToIp;
import static org.slf4j.LoggerFactory.getLogger;


/**
 * Tunnel convert utils.
 */
public final class TunnelConverter {

    private static final Logger log = getLogger(TunnelConverter.class);
    private static final String DEFAULT_PATH_NAME = "ietfPath";
    private static final String DEFAULT_PATH_CONSTRAINT = "ietfPath";
    private static final int DEFAULT_PATH_PREFERENCE = 1;
    private static final boolean DEFAULT_CSPF_STATE = true;
    private static final boolean DEFAULT_LOCKDOWN_STATE = true;

    // no instantiation
    private TunnelConverter() {
    }

    /**
     * Build a general IETF TE object with a giving tunnel list. for there are
     * many kind of attributes in IETF TE, now we only care about the tunnel
     * attributes.
     *
     * @param tunnels tunnels in the TE network
     * @return IETF te info in the TE network
     */
    public static IetfTe buildIetfTeWithTunnels(List<Tunnel> tunnels) {
        Tunnels teTunnels = new DefaultTunnels
                .TunnelsBuilder()
                .tunnel(tunnels)
                .build();
        Te te = new DefaultTe
                .TeBuilder()
                .tunnels(teTunnels)
                .build();
        return new IetfTeOpParam
                .IetfTeBuilder()
                .te(te)
                .yangIetfTeOpType(IetfTe.OnosYangOpType.NONE)
                .build();
    }

    public static IetfTe buildIetfTe(TeTunnel teTunnel) {
        Tunnel tunnel = te2YangTunnelConverter(teTunnel);
        return buildIetfTeWithTunnels(Lists.newArrayList(tunnel));
    }

    /**
     * Converts a specific te tunnel defined in the APP to the general te tunnel
     * defined in YANG model.
     *
     * @param tunnel te tunnel defined in APP
     * @return tunnel defined in YANG model
     */
    public static Tunnel te2YangTunnelConverter(TeTunnel tunnel) {
        List<PrimaryPaths> pathsList = new ArrayList<>();
        //TODO add path info after yang tool change to guava from google-collect
        tunnel.primaryPaths()
                .forEach(tePath -> pathsList.add(te2YangPrimaryPath(tePath)));

        Tunnel.TunnelBuilder builder = new DefaultTunnel
                .TunnelBuilder()
                .type(te2YangTunnelType(tunnel.type()))
                .name(tunnel.name())
                .identifier(tunnel.teTunnelKey().teTunnelId())
                .state(te2YangTunnelState(tunnel))
                .primaryPaths(pathsList);

        return builder.build();
    }

    private static State te2YangTunnelState(TeTunnel tunnel) {
        State.StateBuilder stateBuilder = new DefaultState.StateBuilder();
        stateBuilder.name(tunnel.name())
                .identifier((int) tunnel.teTunnelKey().teTunnelId())
                .source((longToIp(tunnel.srcNode().teNodeId())))
                .destination((longToIp(tunnel.dstNode().teNodeId())))
                .srcTpId(longToByte(tunnel.srcTp().ttpId()))
                .dstTpId(longToByte(tunnel.dstTp().ttpId()))
                .adminStatus(te2YangStateType(tunnel.adminStatus()))
                .lspProtectionType(
                        te2YangProtectionType(tunnel.lspProtectionType()))
                .type(te2YangTunnelType(tunnel.type()))
                .build();
        return stateBuilder.build();
    }

    private static PrimaryPaths te2YangPrimaryPath(TePath tePath) {
        DefaultPrimaryPaths.PrimaryPathsBuilder builder = new DefaultPrimaryPaths
                .PrimaryPathsBuilder()
                .name(DEFAULT_PATH_NAME)
                .preference(DEFAULT_PATH_PREFERENCE)
                .state(te2YangPrimaryPathState(tePath))
                .yangPrimaryPathsOpType(IetfTe.OnosYangOpType.NONE);
        return builder.build();
    }

    private static org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
            .te.rev20160705.ietfte.p2pprimarypathparams.State
    te2YangPrimaryPathState(TePath tePath) {

        List<TeRouteSubobject> teRouteSubobjects = tePath.explicitRoute();

        List<ExplicitRouteObjects> routeObjects = new ArrayList<>();
        teRouteSubobjects.forEach(teRouteSubobject -> {
            routeObjects.add(te2YangRouteSubobject(teRouteSubobject));
        });
        DefaultExplicit.ExplicitBuilder explicitBuilder =
                DefaultExplicit.builder().explicitRouteObjects(routeObjects);

        return new org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.
                te.rev20160705.ietfte.p2pprimarypathparams.DefaultState
                .StateBuilder()
                .type(explicitBuilder.build())
                .pathNamedConstraint(DEFAULT_PATH_CONSTRAINT)
                .noCspf(DEFAULT_CSPF_STATE)
                .lockdown(DEFAULT_LOCKDOWN_STATE)
                .build();
    }

    private static ExplicitRouteObjects
    te2YangRouteSubobject(TeRouteSubobject routeSubobject) {

        TeRouteSubobject.Type type = routeSubobject.type();
        UnnumberedLink yanglink = null;
        //TODO implement other kind of TeRouteSubobject type
        if (type == UNNUMBERED_LINK) {
            DefaultTeRouteUnnumberedLink unnumberedLink =
                    (DefaultTeRouteUnnumberedLink) routeSubobject;
            TeNodeKey nodeKey = unnumberedLink.node();
            TtpKey ttpKey = unnumberedLink.ttp();

            yanglink = DefaultUnnumberedLink.builder()
                    .routerId(longToIp(nodeKey.teNodeId()))
                    .interfaceId(ttpKey.ttpId())
                    .build();

        }

        //TODO implement other kind of explicitRoute usage type
        return DefaultExplicitRouteObjects.builder()
                .type(yanglink)
                .explicitRouteUsage(RouteIncludeEro.class)
                .build();
    }

    /**
     * Converts a YANG TE tunnel defined in the YANG model to a specific TE
     * tunnel defined in the TE tunnel APP.
     *
     * @param tunnel      yang tunnel object
     * @param topologyKey key of the TE topology to which this tunnel belongs
     * @return default Te tunnel defined in TE tunnel APP
     */
    public static DefaultTeTunnel yang2TeTunnel(org.onosproject.yang.gen.v1.
                                                        urn.ietf.params.xml.
                                                        ns.yang.ietf.te.
                                                        rev20160705.ietfte.
                                                        tunnelsgrouping.
                                                        tunnels.Tunnel
                                                        tunnel,
                                                TeTopologyKey topologyKey) {
        //get config info
        Config config = tunnel.config();

        //build basic attribute, node and ttp
        TeNodeKey srcNodeKey = new TeNodeKey(topologyKey, ipToLong(config.source()));
        TeNodeKey dstNodeKey = new TeNodeKey(topologyKey, ipToLong(config.destination()));

        TtpKey srcTtpKey = new TtpKey(srcNodeKey, bytesToLong(config.srcTpId()));
        TtpKey dstTtpKey = new TtpKey(srcNodeKey, bytesToLong(config.dstTpId()));

        //check if paths have been set
        List<PrimaryPaths> primaryPaths = tunnel.primaryPaths();
        List<TePath> paths = new ArrayList<>();
        primaryPaths.forEach(primaryPath -> paths.add(
                yang2TePrimaryPaths(primaryPath, topologyKey)));

        //build the te tunnel
        DefaultTeTunnel.Builder builder = new DefaultTeTunnel.Builder();

        return builder.teTunnelKey(new TeTunnelKey(topologyKey, config.identifier()))
                .name(config.name())
                .type(yang2TeTunnelType(config.type()))
                .lspProtectionType(yang2TeProtectionType(config.lspProtectionType()))
                .adminState(yang2TeStateType(config.adminStatus()))
                .srcNode(srcNodeKey)
                .dstNode(dstNodeKey)
                .srcTp(srcTtpKey)
                .dstTp(dstTtpKey)
                .primaryPaths(paths).build();
    }

    private static TePath yang2TePrimaryPaths(PrimaryPaths primaryPath,
                                              TeTopologyKey topologyKey) {
        org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.
                rev20160705.ietfte.p2pprimarypathparams.Config
                pathConfig = primaryPath.config();

        TePath tePath;
        TePath.Type tePathType = null;
        Type type = pathConfig.type();

        if (type == null) {
            return new DefaultTePath(TePath.Type.DYNAMIC,
                                     Lists.newArrayList(),
                                     Lists.newArrayList(),
                                     Lists.newArrayList());
        }

        Class<? extends Type> typeClass = type.getClass();

        List<TeRouteSubobject> routeSubobjects = new ArrayList<>();

        if (typeClass.isAssignableFrom(DefaultExplicit.class)) {
            DefaultExplicit explicitPath = (DefaultExplicit) type;
            explicitPath
                    .explicitRouteObjects()
                    .forEach(o -> routeSubobjects.add(
                            yang2TeRouteSubobject(o, topologyKey)));
            tePathType = TePath.Type.EXPLICIT;

        } else if (typeClass.isAssignableFrom(DefaultDynamic.class)) {
            tePathType = TePath.Type.DYNAMIC;
        }

        tePath = new DefaultTePath(tePathType,
                                   Lists.newArrayList(),
                                   routeSubobjects,
                                   Lists.newArrayList());
        return tePath;
    }

    private static TeRouteSubobject
    yang2TeRouteSubobject(ExplicitRouteObjects routeObject,
                          TeTopologyKey topologyKey) {

        //TODO implement other types of route type
        DefaultUnnumberedLink type = (DefaultUnnumberedLink) routeObject.type();
        TeNodeKey nodeKey = new TeNodeKey(topologyKey, ipToLong(type.routerId()));
        TtpKey tpId = new TtpKey(nodeKey, type.interfaceId());
        return new DefaultTeRouteUnnumberedLink(nodeKey, tpId);
    }

    private static TeTunnel.Type yang2TeTunnelType(Class type) {
        TeTunnel.Type tunnelType = null;
        if (type.isAssignableFrom(TunnelP2Mp.class)) {
            tunnelType = TeTunnel.Type.P2MP;
        } else if (type.isAssignableFrom(TunnelP2p.class)) {
            tunnelType = TeTunnel.Type.P2P;
        } else if (type.isAssignableFrom(PathSignalingRsvpte.class)) {
            tunnelType = TeTunnel.Type.PATH_SIGNALING_RSVPTE;
        } else if (type.isAssignableFrom(PathSignalingSr.class)) {
            tunnelType = TeTunnel.Type.PATH_SIGNALING_SR;
        }
        return tunnelType;
    }


    private static Class<? extends TunnelType> te2YangTunnelType(TeTunnel.Type type) {
        Class<? extends TunnelType> tunnelType = null;
        switch (type) {

            case P2P:
                tunnelType = TunnelP2p.class;
                break;
            case P2MP:
                tunnelType = TunnelP2Mp.class;
                break;
            case PATH_SIGNALING_RSVPTE:
                tunnelType = PathSignalingRsvpte.class;

                break;
            case PATH_SIGNALING_SR:
                tunnelType = PathSignalingSr.class;
                break;
            default:
                log.error("Unknown te tunnel type {}", type.toString());
        }
        return tunnelType;
    }

    private static LspProtectionType
    yang2TeProtectionType(Class<? extends LspProtType> protType) {
        LspProtectionType type = null;
        if (protType.isAssignableFrom(LspProt1Forn.class)) {
            type = LspProtectionType.LSP_PROT_1_FOR_N;
        } else if (protType.isAssignableFrom(LspProtBidir1To1.class)) {
            type = LspProtectionType.LSP_PROT_BIDIR_1_TO_1;
        } else if (protType.isAssignableFrom(LspProtReroute.class)) {
            type = LspProtectionType.LSP_PROT_REROUTE;
        } else if (protType.isAssignableFrom(LspProtRerouteExtra.class)) {
            type = LspProtectionType.LSP_PROT_REROUTE_EXTRA;
        } else if (protType.isAssignableFrom(LspProtUnidir1To1.class)) {
            type = LspProtectionType.LSP_PROT_UNIDIR_1_TO_1;
        } else if (protType.isAssignableFrom(LspProtUnprotected.class)) {
            type = LspProtectionType.LSP_PROT_UNPROTECTED;
        }
        return type;
    }

    private static Class<? extends LspProtType>
    te2YangProtectionType(LspProtectionType protType) {
        Class<? extends LspProtType> type = null;
        switch (protType) {

            case LSP_PROT_UNPROTECTED:
                type = LspProtUnprotected.class;
                break;
            case LSP_PROT_REROUTE:
                type = LspProtReroute.class;
                break;
            case LSP_PROT_REROUTE_EXTRA:
                type = LspProtRerouteExtra.class;
                break;
            case LSP_PROT_UNIDIR_1_TO_1:
                type = LspProtUnidir1To1.class;
                break;
            case LSP_PROT_BIDIR_1_TO_1:
                type = LspProtBidir1To1.class;
                break;
            case LSP_PROT_1_FOR_N:
                type = LspProt1Forn.class;
                break;
            default:
                log.error("Unknown te tunnel type {}", protType.toString());
        }
        return type;
    }

    private static TeTunnel.State
    yang2TeStateType(Class<? extends org.onosproject.yang.gen.v1.urn.ietf.
            params.xml.ns.yang.ietf.te.types.
            rev20160705.ietftetypes.StateType> stateType) {
        TeTunnel.State teStateType = null;
        if (stateType.isAssignableFrom(StateUp.class)) {
            teStateType = TeTunnel.State.UP;
        } else if (stateType.isAssignableFrom(StateDown.class)) {
            teStateType = TeTunnel.State.DOWN;
        }
        return teStateType;
    }

    private static Class<? extends org.onosproject.yang.gen.v1.urn.ietf.params.
            xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.StateType>
    te2YangStateType(TeTunnel.State stateType) {
        Class<? extends org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.
                ietf.te.types.rev20160705.ietftetypes.StateType> state = null;

        switch (stateType) {

            case DOWN:
                state = StateDown.class;
                break;
            case UP:
                state = StateUp.class;
                break;
            default:
                log.error("Unknown te tunnel type {}", stateType.toString());

        }
        return state;
    }
}
