/*
 * Copyright 2017-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.drivers.polatis.netconf;

import org.apache.commons.configuration.HierarchicalConfiguration;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
import org.onosproject.net.device.DefaultDeviceDescription;
import org.onosproject.net.device.DeviceDescription;
import org.onosproject.net.device.DeviceDescriptionDiscovery;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.device.PortDescription;
import org.onosproject.net.driver.AbstractHandlerBehaviour;

import static org.onosproject.net.optical.device.OmsPortHelper.omsPortDescription;

import org.onlab.util.Frequency;
import org.onlab.util.Spectrum;

import org.slf4j.Logger;
import static org.slf4j.LoggerFactory.getLogger;

import java.util.List;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.net.Device.Type.FIBER_SWITCH;

import static org.onosproject.drivers.polatis.netconf.PolatisNetconfUtility.netconfGet;
import static org.onosproject.drivers.polatis.netconf.PolatisNetconfUtility.configAt;
import static org.onosproject.drivers.polatis.netconf.PolatisNetconfUtility.configsAt;
import static org.onosproject.drivers.polatis.netconf.PolatisNetconfUtility.xmlOpen;
import static org.onosproject.drivers.polatis.netconf.PolatisNetconfUtility.xmlClose;
import static org.onosproject.drivers.polatis.netconf.PolatisNetconfUtility.xmlEmpty;
import static org.onosproject.drivers.polatis.netconf.PolatisNetconfUtility.KEY_PORT;
import static org.onosproject.drivers.polatis.netconf.PolatisNetconfUtility.KEY_PORTID;
import static org.onosproject.drivers.polatis.netconf.PolatisNetconfUtility.KEY_PORTCONFIG;
import static org.onosproject.drivers.polatis.netconf.PolatisNetconfUtility.KEY_PRODINF;
import static org.onosproject.drivers.polatis.netconf.PolatisNetconfUtility.KEY_PORTCONFIG_XMLNS;
import static org.onosproject.drivers.polatis.netconf.PolatisNetconfUtility.KEY_PRODINF_XMLNS;
import static org.onosproject.drivers.polatis.netconf.PolatisNetconfUtility.KEY_DATA_PRODINF;
import static org.onosproject.drivers.polatis.netconf.PolatisNetconfUtility.KEY_DATA_PORTCONFIG;

/**
 * Representation of device information and ports via NETCONF for all Polatis
 * optical circuit switches.
 */
public class PolatisDeviceDescription extends AbstractHandlerBehaviour
    implements DeviceDescriptionDiscovery {

    public static final String DEFAULT_MANUFACTURER = "Polatis";
    public static final String DEFAULT_DESCRIPTION_DATA = "Unknown";
    public static final String KEY_MANUFACTURER = "manufacturer";
    public static final String KEY_HWVERSION = "model-name";
    public static final String KEY_SWVERSION = "software-version";
    public static final String KEY_SERIALNUMBER = "serial-number";
    public static final String KEY_PORTSTATUS = "status";
    public static final String PORT_ENABLED = "ENABLED";
    public static final String KEY_PORTLABEL = "label";
    public static final int POLATIS_NUM_OF_WAVELENGTHS = 39;

    private final Logger log = getLogger(getClass());

    /**
     * Discovers device details, for polatis device by getting the system
     * information.
     *
     * @return device description
     */
    @Override
    public DeviceDescription discoverDeviceDetails() {
        return parseProductInformation();
    }

    private DeviceDescription parseProductInformation() {
        DeviceService devsvc = checkNotNull(handler().get(DeviceService.class));
        DeviceId devid = handler().data().deviceId();
        Device dev = devsvc.getDevice(devid);
        if (dev == null) {
            return new DefaultDeviceDescription(dev.id().uri(), FIBER_SWITCH,
                    DEFAULT_MANUFACTURER, DEFAULT_DESCRIPTION_DATA,
                    DEFAULT_DESCRIPTION_DATA, DEFAULT_DESCRIPTION_DATA,
                    dev.chassisId());
        }
        String reply = netconfGet(handler(), getProductInformationFilter());
        HierarchicalConfiguration cfg = configAt(reply, KEY_DATA_PRODINF);
        return new DefaultDeviceDescription(dev.id().uri(), FIBER_SWITCH,
                cfg.getString(KEY_MANUFACTURER), cfg.getString(KEY_HWVERSION),
                cfg.getString(KEY_SWVERSION), cfg.getString(KEY_SERIALNUMBER),
                dev.chassisId());
    }

    private String getProductInformationFilter() {
        return new StringBuilder(xmlOpen(KEY_PRODINF_XMLNS))
                .append(xmlClose(KEY_PRODINF))
                .toString();
    }

    /**
     * Discovers port details, for polatis device.
     *
     * @return port list
     */
    @Override
    public List<PortDescription> discoverPortDetails() {
        String reply = netconfGet(handler(), getPortsFilter());
        List<PortDescription> descriptions = parsePorts(reply);
        return ImmutableList.copyOf(descriptions);
    }

    private String getPortsFilter() {
        return new StringBuilder(xmlOpen(KEY_PORTCONFIG_XMLNS))
                .append(xmlOpen(KEY_PORT))
                .append(xmlEmpty(KEY_PORTID))
                .append(xmlEmpty(KEY_PORTSTATUS))
                .append(xmlEmpty(KEY_PORTLABEL))
                .append(xmlClose(KEY_PORT))
                .append(xmlClose(KEY_PORTCONFIG))
                .toString();
    }

    private List<PortDescription> parsePorts(String content) {
        List<HierarchicalConfiguration> subtrees = configsAt(content, KEY_DATA_PORTCONFIG);
        List<PortDescription> portDescriptions = Lists.newArrayList();
        for (HierarchicalConfiguration portConfig : subtrees) {
            portDescriptions.add(parsePort(portConfig));
        }
        return portDescriptions;
    }

    private PortDescription parsePort(HierarchicalConfiguration cfg) {
        PortNumber portNumber = PortNumber.portNumber(cfg.getLong(KEY_PORTID));
        DefaultAnnotations annotations = DefaultAnnotations.builder()
                .set(AnnotationKeys.PORT_NAME, cfg.getString(KEY_PORTLABEL))
                .build();
        return omsPortDescription(portNumber,
                cfg.getString(KEY_PORTSTATUS).equals(PORT_ENABLED),
                Spectrum.O_BAND_MIN, Spectrum.L_BAND_MAX,
                Frequency.ofGHz((Spectrum.O_BAND_MIN.asGHz() -
                        Spectrum.L_BAND_MAX.asGHz()) /
                    POLATIS_NUM_OF_WAVELENGTHS), annotations);
    }
}
