class ConfigBuilder {

    public Config build() {

        boolean generateKeyStoreIfNotExisted = false;

        SslConfig sslConfig =
                new SslConfig(
                        sslAuthenticationMode,
                        generateKeyStoreIfNotExisted,
                        toPath(workDir, sslServerKeyStorePath),
                        sslServerKeyStorePassword,
                        toPath(workDir, sslServerTrustStorePath),
                        sslServerTrustStorePassword,
                        sslServerTrustMode,
                        toPath(workDir, sslClientKeyStorePath),
                        sslClientKeyStorePassword,
                        toPath(workDir, sslClientTrustStorePath),
                        sslClientTrustStorePassword,
                        sslClientTrustMode,
                        toPath(workDir, sslKnownClientsFile),
                        toPath(workDir, sslKnownServersFile),
                        sslServerTrustCertificates.stream()
                                .filter(Objects::nonNull)
                                .map(v -> toPath(workDir, v))
                                .collect(Collectors.toList()),
                        sslClientTrustCertificates.stream()
                                .filter(Objects::nonNull)
                                .map(v -> toPath(workDir, v))
                                .collect(Collectors.toList()),
                        toPath(workDir, sslServerTlsKeyPath),
                        toPath(workDir, sslServerTlsCertificatePath),
                        toPath(workDir, sslClientTlsKeyPath),
                        toPath(workDir, sslClientTlsCertificatePath),
                        null);

        final String unixPath =
                Optional.ofNullable(toPath(workDir, unixSocketFile))
                        .map(Path::toAbsolutePath)
                        .map(Path::toString)
                        .map("unix:"::concat)
                        .orElse(null);
        final ServerConfig q2tConfig = new ServerConfig(Q2T, unixPath, REST, null, null, null);

        final String address = (serverHostname == null) ? null : serverHostname + ":" + serverPort;
        final ServerConfig p2pConfig = new ServerConfig(P2P, address, REST, sslConfig, null, address);

        final List<Peer> peerList;
        if (peers != null) {
            peerList = peers.stream().map(Peer::new).collect(Collectors.toList());
        } else {
            peerList = null;
        }

        final List<String> forwardingKeys = new ArrayList<>();
        if (alwaysSendTo != null) {
            for (String keyPath : alwaysSendTo) {
                try {
                    List<String> keysFromFile = Files.readAllLines(toPath(workDir, keyPath));
                    forwardingKeys.addAll(keysFromFile);
                } catch (IOException e) {
                    System.err.println("Error reading alwayssendto file: " + e.getMessage());
                }
            }
        }

        final Config config = new Config();
        config.setServerConfigs(Arrays.asList(q2tConfig, p2pConfig));
        config.setEncryptor(
                new EncryptorConfig() {
                    {
                        setType(EncryptorType.NACL);
                    }
                });

        config.setJdbcConfig(jdbcConfig);
        config.setPeers(peerList);
        config.setAlwaysSendTo(forwardingKeys);
        config.setUseWhiteList(useWhiteList);
        config.setKeys(keyData);
        config.setDisablePeerDiscovery(false);
        return config;
    }

    private  ConfigBuilder();

}