package be.iminds.ilabt.jfed.highlevel.util;

import be.iminds.ilabt.jfed.lowlevel.GeniUser;
import be.iminds.ilabt.jfed.lowlevel.GeniUserProvider;
import be.iminds.ilabt.jfed.lowlevel.connection.JFedConnection;
import be.iminds.ilabt.jfed.lowlevel.ssh_key_info.GeniUserSshKeyInfo;
import be.iminds.ilabt.jfed.lowlevel.ssh_key_info.SshKeyInfoFactory;
import be.iminds.ilabt.jfed.preferences.ProxyPreferencesManager;
import be.iminds.ilabt.jfed.util.SshProxySocketFactory;

import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.net.SocketFactory;
import java.io.IOException;

/**
 * User: twalcari
 * Date: 5/27/2016
 * Time: 09:59
 */
@Singleton
public class ProxySocketFactoryProviderImpl implements ProxySocketFactoryProvider {

    private final GeniUserProvider geniUserProvider;
    private final ProxyPreferencesManager proxyPreferencesManager;

    @Inject
    public ProxySocketFactoryProviderImpl(GeniUserProvider geniUserProvider,
                                          ProxyPreferencesManager proxyPreferencesManager) {
        this.geniUserProvider = geniUserProvider;
        this.proxyPreferencesManager = proxyPreferencesManager;
    }

    @Nullable
    @Override
    public SocketFactory createProxySocketFactory(String forcedTargetHostname, Integer forcedTargetPort) throws IOException {
        if (!proxyPreferencesManager.isProxyEnabledForJfed())
            return null;
        else return createSshProxySocketFactory(forcedTargetHostname, forcedTargetPort, proxyPreferencesManager.isDnsOverProxyRequiredForJFed());
    }

    @Override
    @Nullable
    public SocketFactory createProxySocketFactoryForSsh(String forcedTargetHostname, Integer forcedTargetPort) throws IOException {
        if (!proxyPreferencesManager.isProxyEnabledForSsh())
            return null;
        else return createSshProxySocketFactory(forcedTargetHostname, forcedTargetPort, proxyPreferencesManager.isDnsOverProxyRequiredForSsh());
    }

    private SocketFactory createSshProxySocketFactory(String forcedTargetHostname, Integer forcedTargetPort, boolean forceDnsOverSsh) throws IOException {
        final GeniUser loggedInGeniUser = geniUserProvider.getLoggedInGeniUser();
        assert loggedInGeniUser.getUserAuthorityServer() != null;

        GeniUserSshKeyInfo sshKeyInfo = SshKeyInfoFactory.createGeniUserSshKeyInfo(loggedInGeniUser);

        JFedConnection.SshProxyInfo proxyInfo =
                proxyPreferencesManager.chooseUserProxy(
                        loggedInGeniUser.getUserAuthorityServer().getTestbed().getProxies(),
                        loggedInGeniUser,
                        sshKeyInfo);

        if (forceDnsOverSsh && forcedTargetHostname != null && forcedTargetPort != null)
            return SshProxySocketFactory.createWithForcedTarget(proxyInfo, forcedTargetHostname, forcedTargetPort);
        else
            return SshProxySocketFactory.create(proxyInfo);
    }
}
