package be.iminds.ilabt.jfed;

import be.iminds.ilabt.jfed.fedmon.webapi.client.FedmonWebApiCachedClient;
import be.iminds.ilabt.jfed.fedmon.webapi.client.FedmonWebApiClient;
import be.iminds.ilabt.jfed.fedmon.webapi.client.FedmonWebApiClientConfig;
import be.iminds.ilabt.jfed.fedmon.webapi.client.FedmonWebApiClientPropertiesConfig;
import be.iminds.ilabt.jfed.lowlevel.GeniUser;
import be.iminds.ilabt.jfed.lowlevel.GeniUserProvider;
import be.iminds.ilabt.jfed.preferences.CorePreferenceKey;
import be.iminds.ilabt.jfed.preferences.JFedPreferences;
import be.iminds.ilabt.jfed.util.JFedTrustStore;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import com.google.inject.name.Named;

import javax.inject.Singleton;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Properties;

/**
 * JFedWebApiClientProvider
 */
public class JFedWebApiClientModule extends AbstractModule {
    public static final String DEFAULT_URL_STRING = "https://flsmonitor-api.fed4fire.eu/";
//    public static final String DEFAULT_URL_STRING = "https://flsmonitor-api.fed4fire.eu:8443/";

    public static final String NAMED__NO_CLIENT_AUTH_WEBAPI_URL = "noClientAuthWebApiUrl";
    public static final String NAMED__CLIENT_AUTH_WEBAPI_URL = "clientAuthWebApiUrl";
    public static final String NAMED__NO_CLIENT_AUTH_WEBAPI_CONFIG = "noClientAuthWebApiConfig";
    public static final String NAMED__CLIENT_AUTH_WEBAPI_CONFIG = "clientAuthWebApiConfig";
    public static final String NAMED__NO_CLIENT_AUTH_WEBAPI_CLIENT = "noClientAuthWebApiClient";
    public static final String NAMED__CLIENT_AUTH_WEBAPI_CLIENT = "clientAuthWebApiClient";

    @Override
    protected void configure() {

    }

    @Provides
    @Named(NAMED__NO_CLIENT_AUTH_WEBAPI_URL)
    @Singleton
    private URL provideNoClientAuthWebApiUrl(JFedPreferences jFedPreferences) {
        String userPreference = jFedPreferences.getString(CorePreferenceKey.PREF_JFED_WEBAPI_URL);
        if (userPreference == null || userPreference.trim().isEmpty() ||
                userPreference.trim().equalsIgnoreCase("BUILTIN") || userPreference.trim().equalsIgnoreCase("DEFAULT")) {
            try {
                return new URL(DEFAULT_URL_STRING);
            } catch (MalformedURLException e) {
                throw new RuntimeException("Bug: builtin URL is invalid: \""+DEFAULT_URL_STRING+"\"");
            }
        } else {
            try {
                return new URL(userPreference);
            } catch (MalformedURLException e) {
                throw new RuntimeException("jFed config option \""+CorePreferenceKey.PREF_JFED_WEBAPI_URL.getKey()+"\" has an invalid value: \""+userPreference+"\"", e);
            }
        }
    }

    @Provides
    @Named(NAMED__CLIENT_AUTH_WEBAPI_URL)
    @Singleton
    private URL provideClientAuthWebApiUrl(JFedPreferences jFedPreferences) {
        return provideNoClientAuthWebApiUrl(jFedPreferences);
//        String userPreference = jFedPreferences.getString(CorePreferenceKey.PREF_JFED_WEBAPI_URL);
//        if (userPreference == null || userPreference.trim().isEmpty() ||
//                userPreference.trim().equalsIgnoreCase("BUILTIN") || userPreference.trim().equalsIgnoreCase("DEFAULT")) {
//            try {
//                return new URL(DEFAULT_URL_STRING);
//            } catch (MalformedURLException e) {
//                throw new RuntimeException("Bug: builtin URL is invalid: \""+DEFAULT_URL_STRING+"\"");
//            }
//        } else {
//            try {
//                return new URL(userPreference);
//            } catch (MalformedURLException e) {
//                throw new RuntimeException("jFed config option \""+CorePreferenceKey.PREF_JFED_WEBAPI_URL.getKey()+"\" has an invalid value: \""+userPreference+"\"", e);
//            }
//        }
    }

    @Provides
    @Named(NAMED__CLIENT_AUTH_WEBAPI_CONFIG)
    @Singleton
    private FedmonWebApiClientConfig provideClientAuthWebApiConfig(JFedTrustStore trustStore,
                                                                   @Named(NAMED__CLIENT_AUTH_WEBAPI_URL) URL url,
                                                                   be.iminds.ilabt.jfed.log.Logger logger,
                                                                   GeniUserProvider geniUserProvider) {
        assert geniUserProvider.isUserLoggedIn();

        Properties fedmonWebApiClientConfigProperties = new Properties();
        fedmonWebApiClientConfigProperties.setProperty("webapi_client_url_read_base", url.toExternalForm());
        fedmonWebApiClientConfigProperties.setProperty("webapi_client_url_write_base", url.toExternalForm());

        FedmonWebApiClientConfig fedmonWebApiClientConfig = new FedmonWebApiClientPropertiesConfig(
                fedmonWebApiClientConfigProperties, trustStore, geniUserProvider.getLoggedInGeniUser().getClientCertificateChain(), geniUserProvider.getLoggedInGeniUser().getPrivateKey(), logger);

        return fedmonWebApiClientConfig;
    }

    @Provides
    @Named(NAMED__NO_CLIENT_AUTH_WEBAPI_CONFIG)
    @Singleton
    private FedmonWebApiClientConfig provideNoClientAuthWebApiConfig(JFedTrustStore trustStore,
                                                                     @Named(NAMED__NO_CLIENT_AUTH_WEBAPI_URL) URL url,
                                                                     be.iminds.ilabt.jfed.log.Logger logger) {

        Properties fedmonWebApiClientConfigProperties = new Properties();
        fedmonWebApiClientConfigProperties.setProperty("webapi_client_url_read_base", url.toExternalForm());
        fedmonWebApiClientConfigProperties.setProperty("webapi_client_url_write_base", "http://localhost/"); //no need ever to write

        FedmonWebApiClientConfig fedmonWebApiClientConfig = new FedmonWebApiClientPropertiesConfig(
                fedmonWebApiClientConfigProperties, trustStore, null, null, logger);

        return fedmonWebApiClientConfig;
    }

    @Provides
    @Singleton
    private FedmonWebApiClient provideNoAuthFedmonWebApiClient(
            @Named(NAMED__NO_CLIENT_AUTH_WEBAPI_CONFIG) FedmonWebApiClientConfig fedmonWebApiClientConfig) {
        FedmonWebApiClient fedmonWebApiClient = new FedmonWebApiCachedClient(fedmonWebApiClientConfig);
        return fedmonWebApiClient;
    }
}
