/*
 * Copyright 2015-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.provider.pcep.topology.impl;

import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onlab.packet.ChassisId;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Link.Type;
import org.onosproject.net.SparseAnnotations;
import org.onosproject.net.config.ConfigFactory;
import org.onosproject.net.config.NetworkConfigRegistry;
import org.onosproject.net.config.NetworkConfigService;
import org.onosproject.net.config.basics.SubjectFactories;
import org.onosproject.net.MastershipRole;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.net.device.DefaultDeviceDescription;
import org.onosproject.net.device.DefaultPortDescription;
import org.onosproject.net.device.DeviceDescription;
import org.onosproject.net.device.DeviceProvider;
import org.onosproject.net.device.DeviceProviderRegistry;
import org.onosproject.net.device.DeviceProviderService;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.device.PortDescription;
import org.onosproject.net.link.DefaultLinkDescription;
import org.onosproject.net.link.LinkDescription;
import org.onosproject.net.link.LinkProvider;
import org.onosproject.net.link.LinkProviderRegistry;
import org.onosproject.net.link.LinkProviderService;
import org.onosproject.net.provider.AbstractProvider;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.pcep.api.DeviceCapability;
import org.onosproject.pcep.api.PcepController;
import org.onosproject.pcep.api.PcepDpid;
import org.onosproject.pcep.api.PcepLink;
import org.onosproject.pcep.api.PcepLinkListener;
import org.onosproject.pcep.api.PcepOperator.OperationType;
import org.onosproject.pcep.api.PcepSwitch;
import org.onosproject.pcep.api.PcepSwitchListener;
import org.onosproject.pcep.server.PccId;
import org.onosproject.pcep.server.PcepClient;
import org.onosproject.pcep.server.PcepClientController;
import org.onosproject.pcep.server.PcepNodeListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.net.DeviceId.deviceId;
import static org.onosproject.pcep.api.PcepDpid.uri;

/**
 * Provider which uses an PCEP controller to detect network infrastructure
 * topology.
 */
@Component(immediate = true)
public class PcepTopologyProvider extends AbstractProvider
        implements LinkProvider, DeviceProvider {

    /**
     * Creates instance of PCEP topology provider.
     */
    public PcepTopologyProvider() {
        //In BGP-PCEP app, since both BGP and PCEP topology provider have same scheme
        //so BGP will be primary and PCEP topology provider will be ancillary.
        super(new ProviderId("l3", "org.onosproject.provider.pcep", true));
    }

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

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected LinkProviderRegistry linkProviderRegistry;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected DeviceProviderRegistry deviceProviderRegistry;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected PcepController controller;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected DeviceService deviceService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected PcepClientController pcepClientController;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected NetworkConfigRegistry netConfigRegistry;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected NetworkConfigService netConfigService;

    private DeviceProviderService deviceProviderService;
    private LinkProviderService linkProviderService;

    private HashMap<Long, List<PortDescription>> portMap = new HashMap<>();
    private InternalLinkProvider listener = new InternalLinkProvider();

    private final ConfigFactory<DeviceId, DeviceCapability> configFactory =
            new ConfigFactory<DeviceId, DeviceCapability>(SubjectFactories.DEVICE_SUBJECT_FACTORY,
                    DeviceCapability.class, "deviceCapability", false) {
                @Override
                public DeviceCapability createConfig() {
                    return new DeviceCapability();
                }
            };

    @Activate
    public void activate() {
        linkProviderService = linkProviderRegistry.register(this);
        deviceProviderService = deviceProviderRegistry.register(this);
        controller.addListener(listener);
        controller.addLinkListener(listener);
        pcepClientController.addNodeListener(listener);
        netConfigRegistry.registerConfigFactory(configFactory);
        log.info("Started");
    }

    @Deactivate
    public void deactivate() {
        linkProviderRegistry.unregister(this);
        linkProviderService = null;
        controller.removeListener(listener);
        controller.removeLinkListener(listener);
        pcepClientController.removeNodeListener(listener);
        netConfigRegistry.unregisterConfigFactory(configFactory);
        log.info("Stopped");
    }

    private List<PortDescription> buildPortDescriptions(PcepDpid dpid,
                                                        Port port) {

        List<PortDescription> portList;

        if (portMap.containsKey(dpid.value())) {
            portList = portMap.get(dpid.value());
        } else {
            portList = new ArrayList<>();
        }
        if (port != null) {
            SparseAnnotations annotations = DefaultAnnotations.builder()
                    .putAll(port.annotations()).build();
            portList.add(new DefaultPortDescription(port.number(), port.isEnabled(),
                                                    port.type(), port.portSpeed(),
                                                    annotations));
        }

        portMap.put(dpid.value(), portList);
        return portList;
    }

    /**
     * Build a link description from a pcep link.
     *
     * @param pceLink pcep link
     * @return LinkDescription onos link description
     */
    private LinkDescription buildLinkDescription(PcepLink pceLink) {
        LinkDescription ld;
        checkNotNull(pceLink);
        DeviceId srcDeviceID = deviceId(uri(pceLink.linkSrcDeviceID()));
        DeviceId dstDeviceID = deviceId(uri(pceLink.linkDstDeviceId()));

        deviceProviderService
                .updatePorts(srcDeviceID,
                        buildPortDescriptions(pceLink.linkSrcDeviceID(),
                                pceLink.linkSrcPort()));

        deviceProviderService
                .updatePorts(dstDeviceID,
                        buildPortDescriptions(pceLink.linkDstDeviceId(),
                                pceLink.linkDstPort()));

        ConnectPoint src = new ConnectPoint(srcDeviceID, pceLink.linkSrcPort().number());

        ConnectPoint dst = new ConnectPoint(dstDeviceID, pceLink.linkDstPort().number());

        DefaultAnnotations extendedAttributes = DefaultAnnotations
                .builder()
                .set("subType", String.valueOf(pceLink.linkSubType()))
                .set("workState", pceLink.linkState())
                .set("distance", String.valueOf(pceLink.linkDistance()))
                .set("capType", pceLink.linkCapacityType().toLowerCase())
                .set("avail_" + pceLink.linkCapacityType().toLowerCase(),
                        String.valueOf(pceLink.linkAvailValue()))
                .set("max_" + pceLink.linkCapacityType().toLowerCase(),
                        String.valueOf(pceLink.linkMaxValue())).build();
        // construct the link
        ld = new DefaultLinkDescription(src, dst, Type.OPTICAL, extendedAttributes);
        return ld;
    }

    private class InternalLinkProvider
            implements PcepSwitchListener, PcepLinkListener, PcepNodeListener {

        @Override
        public void switchAdded(PcepDpid dpid) {
            if (deviceProviderService == null) {
                return;
            }
            DeviceId deviceId = deviceId(uri(dpid));
            PcepSwitch sw = controller.getSwitch(dpid);
            checkNotNull(sw, "device should not null.");
            // The default device type is switch.
            ChassisId cId = new ChassisId(dpid.value());
            Device.Type deviceType;

            switch (sw.getDeviceType()) {
                case ROADM:
                    deviceType = Device.Type.ROADM;
                    break;
                case OTN:
                    deviceType = Device.Type.SWITCH;
                    break;
                case ROUTER:
                    deviceType = Device.Type.ROUTER;
                    break;
                default:
                    deviceType = Device.Type.OTHER;
            }

            DeviceDescription description = new DefaultDeviceDescription(
                    deviceId.uri(),
                    deviceType,
                    sw.manufacturerDescription(),
                    sw.hardwareDescription(),
                    sw.softwareDescription(),
                    sw.serialNumber(),
                    cId);
            deviceProviderService.deviceConnected(deviceId, description);

        }

        @Override
        public void switchRemoved(PcepDpid dpid) {
            if (deviceProviderService == null || linkProviderService == null) {
                return;
            }
            deviceProviderService.deviceDisconnected(deviceId(uri(dpid)));

            linkProviderService.linksVanished(DeviceId.deviceId(uri(dpid)));
        }

        @Override
        public void switchChanged(PcepDpid dpid) {
            // TODO Auto-generated method stub

        }

        @Override
        public void handlePceplink(PcepLink link) {

            OperationType operType = link.getOperationType();
            LinkDescription ld = buildLinkDescription(link);
            if (ld == null) {
                log.error("Invalid link info.");
                return;
            }
            switch (operType) {
                case ADD:
                case UPDATE:
                    linkProviderService.linkDetected(ld);
                    break;

                case DELETE:
                    linkProviderService.linkVanished(ld);
                    break;

                default:
                    break;

            }
        }

        @Override
        public void addDevicePcepConfig(PcepClient pc) {
            if (netConfigRegistry == null) {
                log.error("Cannot add PCEP device capability as network config service is not available.");
                return;
            }
            DeviceId pccDeviceId = DeviceId.deviceId(String.valueOf(pc.getPccId().ipAddress()));
            DeviceCapability deviceCap = netConfigService.addConfig(pccDeviceId, DeviceCapability.class);
            deviceCap.setLabelStackCap(pc.capability().labelStackCapability())
                .setLocalLabelCap(pc.capability().pceccCapability())
                .setSrCap(pc.capability().srCapability())
                .apply();
        }

        @Override
        public void deleteDevicePcepConfig(PccId pccId) {
            if (netConfigRegistry == null) {
                log.error("Cannot remove PCEP device capability as network config service is not available.");
                return;
            }
            DeviceId pccDeviceId = DeviceId.deviceId(String.valueOf(pccId.ipAddress()));
            netConfigService.removeConfig(pccDeviceId, DeviceCapability.class);
        }
    }

    @Override
    public void triggerProbe(DeviceId deviceId) {
        // TODO Auto-generated method stub
    }

    @Override
    public void roleChanged(DeviceId deviceId, MastershipRole newRole) {
    }

    @Override
    public boolean isReachable(DeviceId deviceId) {
        // TODO Auto-generated method stub
        return true;
    }

    @Override
    public void changePortState(DeviceId deviceId, PortNumber portNumber,
                                boolean enable) {
        // TODO Auto-generated method stub
    }
}
