/*
 * 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 java.util.List;

import org.onosproject.tetopology.management.api.KeyId;
import org.onosproject.tetopology.management.api.node.TerminationPointKey;
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.NodeId;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev20151208
               .ietfnetworktopology.TpId;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev20151208
               .ietfnetworktopology.networks.network.node.augmentedndnode.DefaultTerminationPoint;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev20151208
               .ietfnetworktopology.networks.network.node.augmentedndnode.TerminationPoint;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev20151208
               .ietfnetworktopology.networks.network.node.augmentedndnode.terminationpoint
                       .DefaultSupportingTerminationPoint;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev20151208
               .ietfnetworktopology.networks.network.node.augmentedndnode.terminationpoint
                       .SupportingTerminationPoint;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708.ietftetopology.interfaceswitchingcapabilitylist.DefaultInterfaceSwitchingCapability;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708.ietftetopology.interfaceswitchingcapabilitylist.InterfaceSwitchingCapability;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708.ietftetopology.interfaceswitchingcapabilitylist.interfaceswitchingcapability.DefaultMaxLspBandwidth;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708.ietftetopology.interfaceswitchingcapabilitylist.interfaceswitchingcapability.MaxLspBandwidth;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
               .ietftetopology.networks.network.node.terminationpoint.AugmentedNtTerminationPoint;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708
               .ietftetopology.networks.network.node.terminationpoint.DefaultAugmentedNtTerminationPoint;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708.ietftetopology.teterminationpointaugment.DefaultTe;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708.ietftetopology.teterminationpointaugment.DefaultTe.TeBuilder;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708.ietftetopology.teterminationpointaugment.te.Config;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708.ietftetopology.teterminationpointaugment.te.DefaultConfig;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708.ietftetopology.teterminationpointaugment.te.DefaultState;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708.ietftetopology.teterminationpointaugment.te.State;
import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.TeTpId;

import com.google.common.collect.Lists;

/**
 * The termination point translations.
 */
public final class TerminationPointConverter {

    private static final String E_NULL_TE_SUBSYSTEM_TP =
            "TeSubsystem terminationPoint object cannot be null";
    private static final String E_NULL_YANG_TP =
            "YANG terminationPoint object cannot be null";

    // no instantiation
    private TerminationPointConverter() {
    }

    /**
     * TerminationPoint object translation from TE Topology subsystem to YANG.
     *
     * @param teSubsystem TE Topology subsystem termination point
     * @return Termination point in YANG Java data structure
     */
    public static TerminationPoint teSubsystem2YangTerminationPoint(org.onosproject.tetopology.management.api.node.
                                                                    TerminationPoint teSubsystem) {
        checkNotNull(teSubsystem, E_NULL_TE_SUBSYSTEM_TP);

        TpId tpId = TpId.fromString(teSubsystem.tpId().toString());
        TerminationPoint.TerminationPointBuilder builder =
                new DefaultTerminationPoint.TerminationPointBuilder().tpId(tpId);

        if (teSubsystem.supportingTpIds() != null) {
            List<SupportingTerminationPoint> tps = Lists.newArrayList();
            SupportingTerminationPoint.SupportingTerminationPointBuilder
                    spTpBuilder = DefaultSupportingTerminationPoint.builder();
            for (TerminationPointKey tpKey : teSubsystem.supportingTpIds()) {
                tps.add(spTpBuilder.networkRef(NetworkId.fromString(tpKey.networkId().toString()))
                                   .nodeRef(NodeId.fromString(tpKey.nodeId().toString()))
                                   .tpRef(TpId.fromString(tpKey.tpId().toString()))
                                   .build());
            }
            builder = builder.supportingTerminationPoint(tps);
        }

        if (teSubsystem.teTpId() != null) {
            AugmentedNtTerminationPoint.AugmentedNtTerminationPointBuilder
                    tpAugmentBuilder = DefaultAugmentedNtTerminationPoint.builder();

            TeBuilder yangTeBuilder = DefaultTe.builder();

            yangTeBuilder = yangTeBuilder.teTpId(TeTpId.fromString((String.valueOf(teSubsystem.teTpId()))));

            Config yConfig = teSubsystem2YangTeAugConfig(teSubsystem);
            yangTeBuilder = yangTeBuilder.config(yConfig);

            State yState = teSubsystem2YangTeAugState(teSubsystem);
            yangTeBuilder = yangTeBuilder.state(yState);

            tpAugmentBuilder = tpAugmentBuilder.te(yangTeBuilder.build());
            builder.addYangAugmentedInfo(tpAugmentBuilder.build(), AugmentedNtTerminationPoint.class);
        }

        return builder.build();
    }

    private static State teSubsystem2YangTeAugState(org.onosproject.tetopology.management.api.node.
            TerminationPoint teSubsystemTe) {
        State.StateBuilder yangStateBuilder = DefaultState.builder();
        // FIXME: interLayerLocks is a list in core but not in yang
//        yangStateBuilder = yangStateBuilder.interLayerLockId(teLink.interLayerLocks().get(0));

        return yangStateBuilder.build();
    }

    private static Config teSubsystem2YangTeAugConfig(org.onosproject.tetopology.management.api.node.
                                                      TerminationPoint teSubsystemTe) {
        Config.ConfigBuilder yangConfigBuilder = DefaultConfig.builder();
        //FIXME: interLayerLocks is a list in core but not in yang
        // yangConfigBuilder =
        // yangConfigBuilder.interLayerLockId(teLink.interLayerLocks().get(0));

        InterfaceSwitchingCapability.InterfaceSwitchingCapabilityBuilder isc =
                DefaultInterfaceSwitchingCapability.builder();

        MaxLspBandwidth.MaxLspBandwidthBuilder maxlspBW = DefaultMaxLspBandwidth
                .builder();
//        for (float f : teLink.maxAvialLspBandwidth()) {
//            // is converting from float to long ok?
//            maxlspBW = maxlspBW.bandwidth(BigDecimal.valueOf((long) f));
//            isc = isc.addToMaxLspBandwidth(maxlspBW.build());
//        }

        yangConfigBuilder = yangConfigBuilder.addToInterfaceSwitchingCapability(isc.build());

        return yangConfigBuilder.build();
    }

    /**
     * TerminationPoint object translation from YANG to TE Topology subsystem.
     *
     * @param yangTp Termination point in YANG Java data structure
     * @return TerminationPoint TE Topology subsystem termination point
     */
    public static org.onosproject.tetopology.management.api.node.TerminationPoint
                      yang2teSubsystemTerminationPoint(TerminationPoint yangTp) {
        checkNotNull(yangTp, E_NULL_YANG_TP);

        org.onosproject.tetopology.management.api.node.DefaultTerminationPoint tp = null;
        List<org.onosproject.tetopology.management.api.node.TerminationPointKey> spTps = null;
        KeyId teTpId = null;

        if (yangTp.supportingTerminationPoint() != null) {
            spTps = Lists.newArrayList();
            for (SupportingTerminationPoint yangSptp : yangTp.supportingTerminationPoint()) {
                org.onosproject.tetopology.management.api.node.TerminationPointKey tpKey =
                        new org.onosproject.tetopology.management.api.node.TerminationPointKey(
                                KeyId.keyId(yangSptp.networkRef().uri().string()),
                                KeyId.keyId(yangSptp.nodeRef().uri().string()),
                                KeyId.keyId(yangSptp.tpRef().uri().string()));
                spTps.add(tpKey);
            }
        }

        if (yangTp.yangAugmentedInfoMap() != null && !yangTp.yangAugmentedInfoMap().isEmpty()) {
            AugmentedNtTerminationPoint yangTpAugment =
                    (AugmentedNtTerminationPoint) yangTp.yangAugmentedInfo(AugmentedNtTerminationPoint.class);
            if (yangTpAugment.te() != null && yangTpAugment.te().teTpId() != null) {
                teTpId = KeyId.keyId(yangTpAugment.te().teTpId().toString());
            }
        }

        tp = new org.onosproject.tetopology.management.api.node
                .DefaultTerminationPoint(KeyId.keyId(yangTp.tpId().uri().string()),
                                         spTps,
                                         Long.valueOf(teTpId.toString()));
        return tp;
    }

}
