/*
 * Copyright 2018-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.juniper;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.drivers.juniper.JuniperUtils.cliDeleteRequestBuilder;
import static org.onosproject.drivers.juniper.JuniperUtils.cliSetRequestBuilder;
import static org.onosproject.drivers.juniper.JuniperUtils.getOpenFlowControllersFromConfig;
import static org.slf4j.LoggerFactory.getLogger;

import com.google.common.collect.Lists;
import org.onosproject.drivers.utilities.XmlConfigParser;

import java.util.List;

import org.onosproject.net.DeviceId;
import org.onosproject.net.behaviour.ControllerConfig;
import org.onosproject.net.behaviour.ControllerInfo;
import org.onosproject.net.driver.AbstractHandlerBehaviour;
import org.onosproject.netconf.NetconfController;
import org.onosproject.netconf.NetconfDevice;
import org.onosproject.netconf.NetconfException;
import org.onosproject.netconf.NetconfSession;
import org.slf4j.Logger;

import java.io.ByteArrayInputStream;

/**
 * Set and get the openflow controller information via NETCONF for Juniper Switch. *
 */
public class ControllerConfigJuniperImpl extends AbstractHandlerBehaviour implements ControllerConfig {

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

    private static final String RPC_TAG_NETCONF_BASE = "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">";
    private static final String RPC_CLOSE_TAG = "</rpc>";

    @Override
    public List<ControllerInfo> getControllers() {
        List<ControllerInfo> controllers = Lists.newArrayList();
        String reply = retrieveResultCommand(buildRpcGetOpenFlowController());

        if (reply == null || reply.isEmpty()) {
            log.error("Cannot get the controllers from switch");
        } else {
            controllers = getOpenFlowControllersFromConfig(XmlConfigParser
                    .loadXml(new ByteArrayInputStream(reply.getBytes())));
            log.debug("controllers {}", controllers);
        }

        return controllers;
    }

    @Override
    public void setControllers(List<ControllerInfo> controllers) {
        if (!requestCommand(buildRpcSetOpenFlowController(controllers))) {
            log.error("Cannot set the controllers to switch");
        }
    }

    @Override
    public void removeControllers(List<ControllerInfo> controllers) {
        if (!requestCommand(buildRpcRemoveOpenFlowController())) {
            log.error("Cannot remove the controllers from switch");
        }
    }

    private String buildRpcGetOpenFlowController() {
        StringBuilder rpc = new StringBuilder(RPC_TAG_NETCONF_BASE);

        rpc.append("<get-configuration>");
        rpc.append("<configuration>");
        rpc.append("<protocols>");
        rpc.append("<openflow>");
        rpc.append("<mode>");
        rpc.append("<ofagent-mode>");
        rpc.append("<controller>");
        rpc.append("</controller>");
        rpc.append("</ofagent-mode>");
        rpc.append("</mode>");
        rpc.append("</openflow>");
        rpc.append("</protocols>");
        rpc.append("</configuration>");
        rpc.append("</get-configuration>");
        rpc.append(RPC_CLOSE_TAG);
        rpc.append("]]>]]>");

        return rpc.toString();
    }

    private String buildRpcSetOpenFlowController(List<ControllerInfo> controllers) {
        StringBuilder request = new StringBuilder();

        request.append("<protocols>");
        request.append("<openflow operation=\"delete\"/>");
        request.append("</protocols>");

        request.append("<protocols>");
        request.append("<openflow>");
        request.append("<mode>");
        request.append("<ofagent-mode>");

        request.append("<controller>");
        for (int i = 0; i < controllers.size(); i++) {
            request.append("<ip>");
            request.append("<name>");
            request.append(controllers.get(i).ip().toString());
            request.append("</name>");
            request.append("<protocol>");
            request.append("<tcp>");
            request.append("<port>");
            request.append(Integer.toString(controllers.get(i).port()));
            request.append("</port>");
            request.append("</tcp>");
            request.append("</protocol>");
            request.append("</ip>");
        }
        request.append("</controller>");
        request.append("</ofagent-mode>");
        request.append("</mode>");
        request.append("</openflow>");
        request.append("</protocols>");

        return cliSetRequestBuilder(request);
    }

    private String buildRpcRemoveOpenFlowController() {
        StringBuilder request = new StringBuilder();

        request.append("<protocols>");
        request.append("<openflow>");
        request.append("<mode>");
        request.append("<ofagent-mode>");
        request.append("<controller operation=\"delete\"/>");
        request.append("</ofagent-mode>");
        request.append("</mode>");
        request.append("</openflow>");
        request.append("</protocols>");

        return cliDeleteRequestBuilder(request);
    }

    private String buildCommit() {
        StringBuilder rpc = new StringBuilder(RPC_TAG_NETCONF_BASE);

        rpc.append("<commit/>");
        rpc.append(RPC_CLOSE_TAG);
        rpc.append("]]>]]>");

        return rpc.toString();
    }

    private String buildDiscardChanges() {
        StringBuilder rpc = new StringBuilder(RPC_TAG_NETCONF_BASE);

        rpc.append("<discard-changes/>");
        rpc.append(RPC_CLOSE_TAG);
        rpc.append("]]>]]>");

        return rpc.toString();
    }

    private NetconfSession getSession() {
        NetconfController controller = checkNotNull(handler().get(NetconfController.class));
        DeviceId deviceId = handler().data().deviceId();
        NetconfDevice device = controller.getDevicesMap().get(deviceId);

        if (device == null) {
            log.error("Cannot find the netconf device : {}", deviceId);
            return null;
        }

        return device.getSession();
    }

    private String retrieveResultCommand(String command) {
        NetconfSession session = getSession();
        String reply;

        if (session == null) {
            log.error("Cannot get session : {}", command);
            return null;
        }

        try {
            reply = session.requestSync(command).trim();
            log.debug(reply);
        } catch (NetconfException e) {
            log.debug(e.getMessage());
            return null;
        }

        return reply;
    }

    private boolean requestCommand(String command) {
        NetconfSession session = getSession();

        if (session == null) {
            log.error("Cannot get session : {}", command);
            return false;
        }

        try {
            String reply = session.requestSync(command).trim();
            log.debug(reply);

            if (!isOK(reply)) {
                log.error("discard changes {}", reply);
                session.requestSync(buildDiscardChanges());
                return false;
            }

            reply = session.requestSync(buildCommit()).trim();
            log.debug(reply);
        } catch (NetconfException e) {
            log.debug(e.getMessage());
            return false;
        }

        return true;
    }

    private boolean isOK(String reply) {
        if (reply != null && reply.indexOf("<ok/>") >= 0) {
            return true;
        }
        return false;
    }
}