package com.lmax.webserver;

import java.io.IOException;
import java.security.GeneralSecurityException;

import com.caucho.cloud.network.NetworkListenSystem;
import com.caucho.config.ConfigException;
import com.caucho.env.service.ResinSystem;
import com.caucho.network.listen.TcpPort;
import com.caucho.resin.PortEmbed;
import com.caucho.server.cluster.ServletService;
import com.caucho.server.http.HttpProtocol;
import com.caucho.vfs.JsseSSLFactory;
import com.caucho.vfs.Path;

public class HttpsEmbed extends PortEmbed
{
    private final Path keyStoreResourcePath;
    private final String alias;
    private final String password;
    private TcpPort port;

    public HttpsEmbed(
            final int httpPort,
            final Path keyStoreResourcePath,
            final String alias,
            final String password)
    {
        this.alias = alias;
        this.password = password;
        setPort(httpPort);
        this.keyStoreResourcePath = keyStoreResourcePath;
    }

    @Override
    public int getLocalPort()
    {
        return getPort();
    }

    @Override
    public void bindTo(final ServletService server)
    {
        try
        {
            port = new TcpPort();

            port.setProtocol(new HttpProtocol());

            port.setPort(getPort());
            port.setAddress(getAddress());

            final JsseSSLFactory jsse = port.createJsse();

            assert keyStoreResourcePath.exists();

            jsse.setPassword(alias);
            jsse.setKeyStoreFile(keyStoreResourcePath);
            jsse.setAlias(password);
            jsse.setKeyStoreType("PKCS12");
            jsse.init();

            port.setSSL(jsse);

            port.init();

            final ResinSystem system = server.getResinSystem();
            NetworkListenSystem listenService = system.getService(NetworkListenSystem.class);
            listenService.addListener(port);
        }
        catch (IOException | GeneralSecurityException e)
        {
            throw ConfigException.create(e);
        }
    }
}
