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

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

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.cluster.ClusterService;
import org.onosproject.cluster.NodeId;
import org.onosproject.mastership.MastershipAdminService;
import org.onosproject.mastership.MastershipService;
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;
import org.onosproject.net.Link.Type;
import org.onosproject.net.MastershipRole;
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.link.LinkService;
import org.onosproject.net.provider.AbstractProvider;
import org.onosproject.net.provider.ProviderId;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;

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 {

    public PcepTopologyProvider() {
        super(new ProviderId("pcep", "org.onosproject.provider.pcep"));
    }

    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 LinkService linkService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected MastershipAdminService mastershipAdminService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected MastershipService mastershipService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected ClusterService clusterService;

    private DeviceProviderService deviceProviderService;
    private LinkProviderService linkProviderService;
    // List<Long> srcportList = new ArrayList<Long>();
    HashSet<Long> portSet = new HashSet<>();
    private InternalLinkProvider listener = new InternalLinkProvider();

    @Activate
    public void activate() {
        linkProviderService = linkProviderRegistry.register(this);
        deviceProviderService = deviceProviderRegistry.register(this);
        controller.addListener(listener);
        controller.addLinkListener(listener);
    }

    @Deactivate
    public void deactivate() {
        linkProviderRegistry.unregister(this);
        linkProviderService = null;
        controller.removeListener(listener);
        controller.removeLinkListener(listener);
    }

    private List<PortDescription> buildPortDescriptions(List<Long> ports,
                                                        String portType) {
        final List<PortDescription> portDescs = new ArrayList<>();
        for (long port : ports) {
            portDescs.add(buildPortDescription(port, portType));
        }
        return portDescs;
    }

    private PortDescription buildPortDescription(long port, String portType) {
        final PortNumber portNo = PortNumber.portNumber(port);
        final boolean enabled = true;
        DefaultAnnotations extendedAttributes = DefaultAnnotations.builder()
                .set("portType", portType).build();
        return new DefaultPortDescription(portNo, enabled, extendedAttributes);
    }

    /**
     * Build link annotations from pcep link description.the annotations consist
     * of lots of property of Huawei device.
     *
     * @param linkDesc
     * @return
     */
    private DefaultAnnotations buildLinkAnnotations(PcepLink linkDesc) {
        DefaultAnnotations extendedAttributes = DefaultAnnotations
                .builder()
                .set("subType", String.valueOf(linkDesc.linkSubType()))
                .set("workState", linkDesc.linkState())
                .set("distance", String.valueOf(linkDesc.linkDistance()))
                .set("capType", linkDesc.linkCapacityType().toLowerCase())
                .set("avail_" + linkDesc.linkCapacityType().toLowerCase(),
                     String.valueOf(linkDesc.linkAvailValue()))
                .set("max_" + linkDesc.linkCapacityType().toLowerCase(),
                     String.valueOf(linkDesc.linkMaxValue())).build();

        return extendedAttributes;
    }

    /**
     * Build a LinkDescription from a PCEPLink.
     *
     * @param pceLink
     * @return LinkDescription
     */
    private LinkDescription buildLinkDescription(PcepLink pceLink) {
        LinkDescription ld;

        DeviceId srcDeviceID = deviceId(uri(pceLink.linkSrcDeviceID()));
        DeviceId dstDeviceID = deviceId(uri(pceLink.linkDstDeviceId()));

        if (deviceService.getDevice(srcDeviceID) == null
                || deviceService.getDevice(dstDeviceID) == null) {
            log.info("the device of the link is not exited" + srcDeviceID
                    + dstDeviceID);
            return null;
        }
        // update port info
        long srcPort = pceLink.linkSrcPort();
        portSet.add(srcPort);
        List<Long> srcportList = new ArrayList<Long>();
        srcportList.addAll(portSet);
        deviceProviderService
                .updatePorts(srcDeviceID,
                             buildPortDescriptions(srcportList,
                                                   pceLink.portType()));

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

        ConnectPoint dst = new ConnectPoint(dstDeviceID,
                                            PortNumber.portNumber(pceLink
                                                    .linkDstPort()));
        DefaultAnnotations extendedAttributes = buildLinkAnnotations(pceLink);

        // construct the link
        ld = new DefaultLinkDescription(src, dst, Type.OPTICAL,
                                        extendedAttributes);
        return ld;
    }

    private void processLinkUpdate(LinkDescription linkDescription) {

        // dst changed, delete the original link,if the dst device is not in
        // other links ,delete it.
        if (linkService.getLink(linkDescription.src(), linkDescription.dst()) == null) {
            // in face,one src one link
            Set<Link> links = linkService
                    .getIngressLinks(linkDescription.src());
            for (Link link : links) {
                linkProviderService.linkVanished((LinkDescription) link);
                if (linkService.getDeviceLinks(link.dst().deviceId()).size() == 0) {
                    deviceProviderService.deviceDisconnected(link.dst()
                            .deviceId());
                }
            }

        }
        linkProviderService.linkDetected(linkDescription);

    }

    private class InternalLinkProvider
            implements PcepSwitchListener, PcepLinkListener {

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

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

            // Device subType: ROADM,OTN,ROUTER.
            DefaultAnnotations extendedAttributes = DefaultAnnotations
                    .builder()
                    .set("subType", String.valueOf(sw.getDeviceSubType()))
                    .build();

            DeviceDescription description = new DefaultDeviceDescription(
                                                                         devicdId.uri(),
                                                                         deviceType,
                                                                         sw.manufacturerDescription(),
                                                                         sw.hardwareDescription(),
                                                                         sw.softwareDescription(),
                                                                         sw.serialNumber(),
                                                                         cId,
                                                                         extendedAttributes);
            NodeId localNode = clusterService.getLocalNode().id();
            mastershipAdminService.setRole(localNode, devicdId,
                                           MastershipRole.MASTER);
            mastershipService.relinquishMastership(devicdId);
            deviceProviderService.deviceConnected(devicdId, description);

        }

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

            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:
                linkProviderService.linkDetected(ld);
                break;
            case UPDATE:
                processLinkUpdate(ld);
                break;

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

            default:
                break;

            }
        }

    }

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

    }

    @Override
    public void roleChanged(DeviceId deviceId, MastershipRole newRole) {
        // NodeId localNode = clusterService.getLocalNode().id();
        // mastershipService.setRole(localNode, deviceId, newRole);

    }

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