/*
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
 * agreements. See the NOTICE file distributed with this work for additional information regarding
 * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance with the License. You may obtain a
 * copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package org.apache.geode.experimental.driver;

import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.Objects;

import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;

public class SocketFactory {
  private InetAddress host;
  private int port;
  private int timeout = -1;
  private String keyStorePath;
  private String trustStorePath;
  private String protocols;
  private String ciphers;

  public SocketFactory() {
    // Do nothing.
  }

  public InetAddress getHost() {
    return host;
  }

  public SocketFactory setHost(InetAddress host) {
    this.host = host;
    return this;
  }

  public int getPort() {
    return port;
  }

  public SocketFactory setPort(int port) {
    this.port = port;
    return this;
  }

  public int getTimeout() {
    return timeout;
  }

  public SocketFactory setTimeout(int timeout) {
    this.timeout = timeout;
    return this;
  }

  public String getKeyStorePath() {
    return keyStorePath;
  }

  public SocketFactory setKeyStorePath(String keyStorePath) {
    this.keyStorePath = keyStorePath;
    return this;
  }

  public String getTrustStorePath() {
    return trustStorePath;
  }

  public SocketFactory setTrustStorePath(String trustStorePath) {
    this.trustStorePath = trustStorePath;
    return this;
  }

  public String getProtocols() {
    return protocols;
  }

  public SocketFactory setProtocols(String protocols) {
    this.protocols = protocols;
    return this;
  }

  public String getCiphers() {
    return ciphers;
  }

  public SocketFactory setCiphers(String ciphers) {
    this.ciphers = ciphers;
    return this;
  }

  public boolean isSsl() {
    return (!Objects.isNull(keyStorePath) && !keyStorePath.isEmpty())
        || (!Objects.isNull(trustStorePath) && !trustStorePath.isEmpty());
  }

  public Socket connect() throws GeneralSecurityException, IOException {
    Socket socket;

    SocketAddress sockaddr = new InetSocketAddress(host, port);
    if (isSsl()) {
      final SSLContext sslContext = getSSLContextInstance();
      final KeyManager[] keyManagers = getKeyManagers();
      final TrustManager[] trustManagers = getTrustManagers();
      sslContext.init(keyManagers, trustManagers, null /* use the default secure random */);

      javax.net.SocketFactory socketFactory = sslContext.getSocketFactory();
      socket = socketFactory.createSocket();

      socket.connect(sockaddr, Math.max(timeout, 0));
      if (socket instanceof SSLSocket) {
        SSLSocket sslSocket = (SSLSocket) socket;
        sslSocket.setUseClientMode(true);
        sslSocket.setEnableSessionCreation(true);
        if (timeout > 0) {
          sslSocket.setSoTimeout(timeout);
        }
        if (protocols != null) {
          sslSocket.setEnabledProtocols(protocols.split(" "));
        }
        if (ciphers != null) {
          sslSocket.setEnabledCipherSuites(ciphers.split(" "));
        }
        sslSocket.startHandshake();
      }
    } else {
      socket = new Socket();
      socket.connect(sockaddr, Math.max(timeout, 0));
    }

    return socket;
  }

  private SSLContext getSSLContextInstance() throws IOException {
    String[] knownAlgorithms = {"SSL", "SSLv2", "SSLv3", "TLS", "TLSv1", "TLSv1.1", "TLSv1.2"};
    for (String algo : knownAlgorithms) {
      try {
        return SSLContext.getInstance(algo);
      } catch (NoSuchAlgorithmException e) {
        // continue
      }
    }
    throw new IOException("SSL not configured correctly, unable create an SSLContext");
  }

  private TrustManager[] getTrustManagers()
      throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException {
    if (Objects.isNull(trustStorePath)) {
      return new TrustManager[0];
    }

    String trustStoreType = "jks";
    KeyStore keyStore = KeyStore.getInstance(trustStoreType);
    char[] password = "password".toCharArray();
    try (FileInputStream fileInputStream = new FileInputStream(trustStorePath)) {
      keyStore.load(fileInputStream, password);
    }

    TrustManagerFactory tmf =
        TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    tmf.init(keyStore);
    return tmf.getTrustManagers();
  }

  private KeyManager[] getKeyManagers() throws KeyStoreException, IOException,
      NoSuchAlgorithmException, CertificateException, UnrecoverableKeyException {
    if (Objects.isNull(keyStorePath)) {
      return new KeyManager[0];
    }

    String keyStoreType = "jks";
    KeyStore keyStore = KeyStore.getInstance(keyStoreType);
    char[] password = "password".toCharArray();
    try (FileInputStream fileInputStream = new FileInputStream(keyStorePath)) {
      keyStore.load(fileInputStream, password);
    }

    KeyManagerFactory keyManagerFactory =
        KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    keyManagerFactory.init(keyStore, password);
    return keyManagerFactory.getKeyManagers();
  }
}
