/*
 * Copyright 2016-present 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.opencord.cordvtn.impl;

import com.google.common.collect.Sets;
import com.google.common.io.CharStreams;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import org.onlab.packet.IpAddress;
import org.opencord.cordvtn.api.NetworkAddress;
import org.opencord.cordvtn.api.SshAccessInfo;
import org.slf4j.Logger;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static org.slf4j.LoggerFactory.getLogger;

/**
 * {@code RemoteIpCommandUtil} provides methods to help execute Linux IP commands to a remote server.
 * It opens individual exec channels for each command. User can create a session with {@code connect}
 * method and then execute a series commands. After done with all commands, the session must be closed
 * explicitly by calling {@code disconnect}.
 */
public final class RemoteIpCommandUtil {

    protected static final Logger log = getLogger(RemoteIpCommandUtil.class);

    private static final String STRICT_HOST_CHECKING = "StrictHostKeyChecking";
    private static final String DEFAULT_STRICT_HOST_CHECKING = "no";
    private static final int DEFAULT_SESSION_TIMEOUT = 60000; // milliseconds

    private static final String IP_PATTERN = "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
            "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
            "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
            "([01]?\\d\\d?|2[0-4]\\d|25[0-5])$";

    private static final String IP_ADDR_SHOW = "sudo ip addr show %s";
    private static final String IP_ADDR_FLUSH = "sudo ip addr flush %s";
    private static final String IP_ADDR_ADD = "sudo ip addr add %s dev %s";
    private static final String IP_ADDR_DELETE = "sudo ip addr delete %s dev %s";
    private static final String IP_LINK_SHOW = "sudo ip link show %s";
    private static final String IP_LINK_UP = "sudo ip link set %s up";

    /**
     * Default constructor.
     */
    private RemoteIpCommandUtil() {
    }

    /**
     * Adds a given IP address to a given device.
     *
     * @param session ssh connection
     * @param ip network address
     * @param device device name to assign the ip address
     * @return true if the command succeeds, or false
     */
    public static boolean addIp(Session session, NetworkAddress ip, String device) {
        if (session == null || !session.isConnected()) {
            return false;
        }

        executeCommand(session, String.format(IP_ADDR_ADD, ip.cidr(), device));
        Set<IpAddress> result = getCurrentIps(session, device);
        return result.contains(ip.ip());
    }

    /**
     * Removes the IP address from a given device.
     *
     * @param session ssh connection
     * @param ip ip address
     * @param device device name
     * @return true if the command succeeds, or false
     */
    public static boolean deleteIp(Session session, IpAddress ip, String device) {
        if (session == null || !session.isConnected()) {
            return false;
        }

        executeCommand(session, String.format(IP_ADDR_DELETE, ip, device));
        Set<IpAddress> result = getCurrentIps(session, device);
        return !result.contains(ip);
    }

    /**
     * Removes all IP address on a given device.
     *
     * @param session ssh connection
     * @param device device name
     * @return true if the command succeeds, or false
     */
    public static boolean flushIp(Session session, String device) {
        if (session == null || !session.isConnected()) {
            return false;
        }

        executeCommand(session, String.format(IP_ADDR_FLUSH, device));
        return getCurrentIps(session, device).isEmpty();
    }

    /**
     * Returns a set of IP address that a given device has.
     *
     * @param session ssh connection
     * @param device device name
     * @return set of IP prefix or empty set
     */
    public static Set<IpAddress> getCurrentIps(Session session, String device) {
        if (session == null || !session.isConnected()) {
            return Sets.newHashSet();
        }

        String output = executeCommand(session, String.format(IP_ADDR_SHOW, device));
        Set<IpAddress> result = Pattern.compile(" |/")
                .splitAsStream(output)
                .filter(s -> s.matches(IP_PATTERN))
                .map(IpAddress::valueOf)
                .collect(Collectors.toSet());

        return result;
    }

    /**
     * Sets link state up for a given device.
     *
     * @param session ssh connection
     * @param device device name
     * @return true if the command succeeds, or false
     */
    public static boolean setInterfaceUp(Session session, String device) {
        if (session == null || !session.isConnected()) {
            return false;
        }

        executeCommand(session, String.format(IP_LINK_UP, device));
        return isInterfaceUp(session, device);
    }

    /**
     * Checks if a given interface is up or not.
     *
     * @param session ssh connection
     * @param device device name
     * @return true if the interface is up, or false
     */
    public static boolean isInterfaceUp(Session session, String device) {
        if (session == null || !session.isConnected()) {
            return false;
        }

        String output = executeCommand(session, String.format(IP_LINK_SHOW, device));
        return output != null && output.contains("UP");
    }

    /**
     * Creates a new session with a given access information.
     *
     * @param sshInfo information to ssh to the remove server
     * @return ssh session, or null
     */
    public static Session connect(SshAccessInfo sshInfo) {
        try {
            JSch jsch = new JSch();
            jsch.addIdentity(sshInfo.privateKey());

            Session session = jsch.getSession(sshInfo.user(),
                                      sshInfo.remoteIp().toString(),
                                      sshInfo.port().toInt());
            session.setConfig(STRICT_HOST_CHECKING, DEFAULT_STRICT_HOST_CHECKING);
            session.connect(DEFAULT_SESSION_TIMEOUT);

            return session;
        } catch (JSchException e) {
            log.debug("Failed to connect to {} due to {}", sshInfo.toString(), e.toString());
            return null;
        }
    }

    /**
     * Closes a connection.
     *
     * @param session session
     */
    public static void disconnect(Session session) {
        if (session != null && session.isConnected()) {
            session.disconnect();
        }
    }

    /**
     * Executes a given command. It opens exec channel for the command and closes
     * the channel when it's done.
     *
     * @param session ssh connection to a remote server
     * @param command command to execute
     * @return command output string if the command succeeds, or null
     */
    private static String executeCommand(Session session, String command) {
        if (session == null || !session.isConnected()) {
            return null;
        }

        log.trace("Execute command {} to {}", command, session.getHost());

        try {
            Channel channel = session.openChannel("exec");
            ((ChannelExec) channel).setCommand(command);
            channel.setInputStream(null);
            InputStream output = channel.getInputStream();

            channel.connect();
            String result = CharStreams.toString(new InputStreamReader(output));
            channel.disconnect();

            return result;
        } catch (JSchException | IOException e) {
            log.debug("Failed to execute command {} due to {}", command, e.toString());
            return null;
        }
    }
}
