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

import com.google.common.base.Preconditions;
import org.onosproject.driver.XmlConfigParser;
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.net.driver.DriverHandler;
import org.onosproject.netconf.NetconfController;
import org.onosproject.netconf.NetconfDevice;
import org.slf4j.Logger;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

import static org.slf4j.LoggerFactory.getLogger;

/**
 * Implementation of controller config which allows to get and set controllers
 * through the Netconf protocol.
 */
public class NetconfControllerConfig extends AbstractHandlerBehaviour
        implements ControllerConfig {

    private final Logger log = getLogger(NetconfControllerConfig.class);

    @Override
    public List<ControllerInfo> getControllers() {
        DriverHandler handler = handler();
        NetconfController controller = handler.get(NetconfController.class);
        DeviceId ofDeviceId = handler.data().deviceId();
        Preconditions.checkNotNull(controller, "Netconf controller is null");
        List<ControllerInfo> controllers = new ArrayList<>();
        try {
            controllers.addAll(XmlConfigParser.parseStreamControllers(XmlConfigParser.
                    loadXml(new ByteArrayInputStream(controller.
                            getDevicesMap().get(ofDeviceId).getSession().
                            getConfig("running").getBytes(StandardCharsets.UTF_8)))));
        } catch (IOException e) {
            log.error("Cannot comunicate to device {} ", ofDeviceId);
        }
        return controllers;
    }

    @Override
    public void setControllers(List<ControllerInfo> controllers) {
        DriverHandler handler = handler();
        NetconfController controller = handler.get(NetconfController.class);
        DeviceId deviceId = handler.data().deviceId();
        Preconditions.checkNotNull(controller, "Netconf controller is null");
        try {
            NetconfDevice device = controller.getNetconfDevice(deviceId);
            log.warn("provider map {}", controller.getDevicesMap());
            String config = null;
            try {
                config = XmlConfigParser.createControllersConfig(
                        XmlConfigParser.loadXml(getClass().getResourceAsStream("controllers.xml")),
                        XmlConfigParser.loadXml(
                                new ByteArrayInputStream(device.getSession()
                                                                 .getConfig("running")
                                                                 .getBytes(
                                                                         StandardCharsets.UTF_8))),
                        "running", "merge", "create", controllers
                );
            } catch (IOException e) {
                log.error("Cannot comunicate to device {} , exception {}", deviceId, e.getMessage());
            }
            device.getSession().editConfig(config.substring(config.indexOf("-->") + 3));
        } catch (NullPointerException e) {
            log.warn("No NETCONF device with requested parameters " + e);
            throw new NullPointerException("No NETCONF device with requested parameters " + e);
        } catch (IOException e) {
            log.error("Cannot comunicate to device {} , exception {}", deviceId, e.getMessage());
        }

    }

    //TODO maybe put method getNetconfClientService like in ovsdb if we need it

}


