package jnet.server.network;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import java.security.cert.CertificateException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.net.ssl.SSLException;

/**
 *
 * @author cucky
 */
public class ServerSsl extends Thread {

    private int port;

    public ServerSsl(int port) {
        this.port = port;
    }

    @Override
    public void run() {

        try {
            
            // Načtení self-signed certifikátu a privátního klíče
            //File certChainFile = new File("cert.pem");
            //File privateKeyFile = new File("key.pem");
            // Vytvoření SSL kontextu
            //SslContext sslContext = SslContextBuilder.forServer(certChainFile, privateKeyFile).build();
            
                        // Self-signed certifikát pro server
                    SelfSignedCertificate ssc = new SelfSignedCertificate();

                    // SSL kontext pro server
                    SslContext sslContext = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey())
                .trustManager(InsecureTrustManagerFactory.INSTANCE) // Nepožadujeme důvěryhodné klientské certifikáty
                .build();
            // Skupiny pro zpracování I/O operací
            EventLoopGroup bossGroup = new NioEventLoopGroup(1);
            EventLoopGroup workerGroup = new NioEventLoopGroup();
            try {
                // Vytvoření ServerBootstrap pro nastavení serveru
                ServerBootstrap serverBootstrap = new ServerBootstrap()
                        .group(bossGroup, workerGroup)
                        .channel(NioServerSocketChannel.class)
                        //.handler(new LoggingHandler(LogLevel.INFO))
                        .childHandler(new ChannelInitializer<SocketChannel>() {
                            @Override
                            protected void initChannel(SocketChannel ch) {
                                ch.pipeline().addLast(sslContext.newHandler(ch.alloc())); // SSL handler
                                ch.pipeline().addLast(new StringDecoder());  // Dekóduje zprávy přijaté od klienta
                                ch.pipeline().addLast(new StringEncoder());  // Kóduje zprávy odeslané klientovi
                                ch.pipeline().addLast(new ServerHandler());  // Vlastní handler pro zpracování zpráv
                            }
                        });
                
                // Bind serveru na specifikovaný port (např. 8080)
                Channel channel = serverBootstrap.bind(port).sync().channel();
                
                System.out.println("ssl Server is ready and listening on port " + port);
                
                // Čekání na ukončení serveru
                channel.closeFuture().sync();
            } catch (Exception ex) {
                Logger.getLogger(ServerSsl.class.getName()).log(Level.SEVERE, null, ex);
            } finally {
                // Uvolnění prostředků
                bossGroup.shutdownGracefully();
                workerGroup.shutdownGracefully();
            }
        } catch (SSLException ex) {
            Logger.getLogger(ServerSsl.class.getName()).log(Level.SEVERE, null, ex);
        } catch (CertificateException ex) {
            Logger.getLogger(ServerSsl.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
