package cz.moneta.test.harness.connectors.rest;

import cz.moneta.test.harness.connectors.Connector;
import org.apache.logging.log4j.jul.LogManager;
import org.glassfish.jersey.SslConfigurator;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.client.HttpUrlConnectorProvider;
import org.glassfish.jersey.jackson.JacksonFeature;
import org.glassfish.jersey.jackson.internal.jackson.jaxrs.json.JacksonJsonProvider;
import org.glassfish.jersey.logging.LoggingFeature;
import org.glassfish.jersey.media.multipart.MultiPartFeature;

import jakarta.ws.rs.client.Client;
import jakarta.ws.rs.client.ClientBuilder;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;

import static cz.moneta.test.harness.constants.HarnessConfigConstants.DEFAULT_REST_READ_TIMEOUT;

public abstract class BaseRestConnector implements Connector {

    protected Client createHttpClient(String loggerName) throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException {
        return createHttpClient(loggerName, DEFAULT_REST_READ_TIMEOUT);
    }

    protected Client createHttpClient(String loggerName, long readTimeout) throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException {
        KeyStore trustedStore = KeyStore.getInstance(KeyStore.getDefaultType());
        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());

        trustedStore.load(getInputStream("keystores/mb_root"), "changeit".toCharArray());
        keyStore.load(getInputStream("keystores/api_gw_client.p12"), "changeit".toCharArray());

        ClientConfig config = new ClientConfig()
                .register(JacksonFeature.class)
                .register(JacksonJsonProvider.class)
                .register(MultiPartFeature.class)
                .register(new LoggingFeature(LogManager.getLogManager().getLogger(loggerName),
                        Level.FINE, LoggingFeature.Verbosity.PAYLOAD_ANY, 1024 * 1024))
                .property(HttpUrlConnectorProvider.SET_METHOD_WORKAROUND, true); // TODO: test it, this line may affect all REST calls

        return ClientBuilder.newBuilder()
                .withConfig(config)
                .connectTimeout(10, TimeUnit.SECONDS)
                .readTimeout(readTimeout, TimeUnit.SECONDS)
                .sslContext(SslConfigurator.newInstance()
                        .trustStore(trustedStore)
                        .keyStore(keyStore)
                        .keyStorePassword("changeit".toCharArray())
                        .createSSLContext())
                .build();
    }

    public InputStream getInputStream(String name) {
        return this.getClass().getClassLoader().getResourceAsStream(name);
    }
}
