/*
 * 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 != 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;
    }
}