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

import com.google.common.collect.Lists;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
import org.onosproject.net.device.DefaultPortDescription;
import org.onosproject.net.device.DefaultPortStatistics;
import org.onosproject.net.device.PortDescription;
import org.onosproject.net.device.PortStatistics;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import static org.onosproject.net.AnnotationKeys.PORT_NAME;
import static org.onosproject.net.Port.Type.COPPER;
import static org.onosproject.net.PortNumber.portNumber;

/**
 * Representation of Huawei XML parser.
 */
public final class HuaweiXmlParser {

    private static final String DATA = "data";
    private static final String IFM = "ifm";
    private static final String IFS = "interfaces";
    private static final String IF = "interface";
    private static final String IF_TYPE = "ifPhyType";
    private static final String IF_STATS = "ifStatistics";
    private static final String IF_STAT = "ifPhyStatus";
    private static final String IF_NUM = "ifNumber";
    private static final String IF_SPEED = "ifOperSpeed";
    private static final String IF_NAME = "ifName";
    private static final String UP = "up";
    private static final String DYN_INFO = "ifDynamicInfo";
    private static final String DELIMITER = "/";
    private static final String SYS = "system";
    private static final String SYS_INFO = "systemInfo";
    private static final String SYS_NAME = "sysName";
    private static final String PDT_VER = "productVer";
    private static final String PLATFORM_VER = "platformVer";
    private static final String SYS_ID = "sysObjectId";
    private static final String P_RCVD = "receivePacket";
    private static final String P_SENT = "sendPacket";
    private static final String B_RCVD = "receiveByte";
    private static final String B_SENT = "sendByte";
    private static final String RX_DROP = "rcvDropPacket";
    private static final String TX_DROP = "sendDropPacket";
    private static final String RX_ERROR = "rcvErrorPacket";
    private static final String TX_ERROR = "sendErrorPacket";

    private static final String DEV_PARSE_ERR = "Unable to parse the received" +
            " xml reply for system details from the huawei device";
    private static final String INT_PARSE_ERR = "Unable to parse the received" +
            " xml reply for interface details from the huawei device";
    private static final String P_NAME_INVALID = "Invalid port name.";

    //TODO: All type of interfaces has to be added.
    private static final List INTERFACES = Arrays.asList(
            "MEth", "Ethernet", "POS", "GigabitEthernet");

    private List<PortDescription> ports = new ArrayList<>();
    private String xml;
    private int portInc;
    private String[] info = new String[4];

    /**
     * Constructs huawei XML parser with xml reply.
     *
     * @param xml xml reply
     */
    public HuaweiXmlParser(String xml) {
        this.xml = xml;
    }

    /**
     * Returns the system info.
     *
     * @return system info
     */
    String[] getInfo() {
        return info;
    }

    /**
     * Returns the port list.
     *
     * @return port list
     */
    List<PortDescription> getPorts() {
        return ports;
    }

    /**
     * Parses system info xml reply.
     */
    void parseSysInfo() {
        Document doc;
        try {
            doc = DocumentHelper.parseText(xml);
        } catch (DocumentException e) {
            throw new IllegalArgumentException(DEV_PARSE_ERR);
        }

        Element root = doc.getRootElement();
        Element parent = root.element(DATA).element(SYS).element(SYS_INFO);
        info[0] = parent.element(SYS_NAME).getText();
        info[1] = parent.element(PDT_VER).getText();
        info[2] = parent.element(PLATFORM_VER).getText();
        info[3] = parent.element(SYS_ID).getText();
    }

    /**
     * Parses interface xml reply and creates ports to be updated.
     */
    void parseInterfaces() {
        Iterator itr = getInterfaceIterator();
        while (itr.hasNext()) {
            Element ifElement = (Element) itr.next();
            addPorts(ifElement);
        }
    }

    private Iterator getInterfaceIterator() {
        Document doc;
        try {
            doc = DocumentHelper.parseText(xml);
        } catch (DocumentException e) {
            throw new IllegalArgumentException(INT_PARSE_ERR);
        }
        Element root = doc.getRootElement();
        Element parent = root.element(DATA).element(IFM).element(IFS);
        return parent.elementIterator(IF);
    }

    /**
     * Adds port information to the port list from the xml reply.
     *
     * @param ifElement interface element
     */
    private void addPorts(Element ifElement) {
        String ifType = ifElement.element(IF_TYPE).getText();

        if (INTERFACES.contains(ifType)) {
            Element info = ifElement.element(DYN_INFO);
            String status = info.element(IF_STAT).getText();
            String port = getPortNum(ifElement.element(IF_NUM).getText());
            String speed = info.element(IF_SPEED).getText();
            String ifName = ifElement.element(IF_NAME).getText();

            boolean isEnabled = false;
            if (status.equals(UP)) {
                isEnabled = true;
            }

            Long portSpeed = 0L;
            if (!speed.isEmpty()) {
                portSpeed = Long.valueOf(speed);
            }

            DefaultAnnotations annotations = DefaultAnnotations.builder()
                    .set(PORT_NAME, ifName).build();
            ports.add(DefaultPortDescription.builder()
                      .withPortNumber(portNumber(port))
                      .isEnabled(isEnabled)
                      .type(COPPER)
                      .portSpeed(portSpeed)
                      .annotations(annotations)
                      .build());
        }
    }

    /**
     * Returns port number from the port name. As many type of port can have
     * same port number, each port number will be prepended with a incrementing
     * number to make it unique in the list.
     *
     * @param portName port name
     * @return port number
     */
    private String getPortNum(String portName) {
        String port;
        if (!portName.contains(DELIMITER)) {
            portInc++;
            port = String.valueOf(portInc) + portName;
        } else if (portName.contains(DELIMITER)) {
            try {
                port = portName.substring(
                        portName.lastIndexOf(DELIMITER) + 1);
                portInc++;
                port = String.valueOf(portInc) + port;
            } catch (StringIndexOutOfBoundsException e) {
                throw new IllegalArgumentException(P_NAME_INVALID);
            }
        } else {
            throw new IllegalArgumentException(P_NAME_INVALID);
        }
        return port;
    }

    /**
     * Returns port statistics information for a device.
     *
     * @param deviceId device for which port statistics to be fetched
     * @return port statistics
     */
    Collection<PortStatistics> parsePortsStatistics(DeviceId deviceId) {
        Collection<PortStatistics> pss = Lists.newArrayList();
        Iterator itr = getInterfaceIterator();
        while (itr.hasNext()) {
            Element ifElement = (Element) itr.next();
            pss.add(getPortStatistics(ifElement, deviceId));
        }
        return pss;
    }

    private PortStatistics getPortStatistics(Element ifElement, DeviceId id) {
        String ifType = ifElement.element(IF_TYPE).getText();

        DefaultPortStatistics.Builder builder = DefaultPortStatistics.builder();

        if (INTERFACES.contains(ifType)) {
            int port = Integer.parseInt(getPortNum(ifElement.element(IF_NUM)
                                                           .getText()));
            Element statInfo = ifElement.element(IF_STATS);
            long packetReceived = Long.parseLong(statInfo.element(P_RCVD)
                                                         .getText());
            long packetSent = Long.parseLong(statInfo.element(P_SENT).getText());
            long bytesReceived = Long.parseLong(statInfo.element(B_RCVD)
                                                        .getText());
            long bytesSent = Long.parseLong(statInfo.element(B_SENT).getText());
            long packetsRxDropped = Long.parseLong(statInfo.element(RX_DROP)
                                                           .getText());
            long packetsTxDropped = Long.parseLong(statInfo.element(TX_DROP)
                                                           .getText());
            long packetsRxErrors = Long.parseLong(statInfo.element(RX_ERROR)
                                                          .getText());
            long packetsTxErrors = Long.parseLong(statInfo.element(TX_ERROR)
                                                          .getText());

            return builder.setDeviceId(id)
                    .setPort(PortNumber.portNumber(port))
                    .setPacketsReceived(packetReceived)
                    .setPacketsSent(packetSent)
                    .setBytesReceived(bytesReceived)
                    .setBytesSent(bytesSent)
                    .setPacketsRxDropped(packetsRxDropped)
                    .setPacketsRxErrors(packetsRxErrors)
                    .setPacketsTxDropped(packetsTxDropped)
                    .setPacketsTxErrors(packetsTxErrors).build();
        }
        return builder.build();
    }
}
