package tutorial.sample21.client;

import java.io.IOException;
import javax.xml.rpc.ServiceException;

import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.UnrecoverableKeyException;

import weblogic.webservice.context.WebServiceContext;
import weblogic.webservice.context.WebServiceSession;
import weblogic.webservice.core.handler.WSSEClientHandler;
import weblogic.xml.security.SecurityAssertion;
import weblogic.xml.security.UserInfo;
import javax.xml.namespace.QName;
import javax.xml.rpc.ServiceException;
import javax.xml.rpc.handler.HandlerInfo;
import javax.xml.rpc.handler.HandlerRegistry;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.Key;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;


public class Main{

  private static final String CLIENT_KEYSTORE = "clientkeystore";
  private static final String KEYSTORE_PASS = "mypasswd";
  private static final String KEYNAME = "clientkey";
  private static final String KEYPASS = "clientpass";
  private static final String USERNAME = "joe";
  private static String PASSWORD = "gumby1234";


  public static void main( String[] args ){

    if( args.length == 1 ){
      new Main( args[0] );
    }else{
      throw new IllegalArgumentException( "URL of the service not specified" );
    }
  }

  public Main( String wsdlUrl ){
    try{
      HelloWorldService service = new HelloWorldService_Impl( wsdlUrl );
      HelloWorldServicePort port = service.getHelloWorldServicePort();

      WebServiceContext context = service.context();
      X509Certificate clientcert = getCertificate(KEYNAME, CLIENT_KEYSTORE);

      PrivateKey clientprivate = 
          (PrivateKey)getPrivateKey(KEYNAME, KEYPASS,CLIENT_KEYSTORE);

      WebServiceSession session = context.getSession();

      session.setAttribute(WSSEClientHandler.CERT_ATTRIBUTE, clientcert);
      session.setAttribute(WSSEClientHandler.KEY_ATTRIBUTE, clientprivate);

      UserInfo ui = new UserInfo(USERNAME, PASSWORD);

      session.setAttribute(WSSEClientHandler.REQUEST_USERINFO, ui);

      World world = port.helloComplexWorld();

      System.out.println( world );
    }catch( IOException e ){
      System.out.println( "Failed to create web service client:" + e );
    }catch( ServiceException e ){
      System.out.println( "Failed to create web service client:" + e );
    }catch( KeyStoreException e ){
      System.out.println( "Failed to create web service client:" + e );
    }catch( CertificateException e ){
      System.out.println( "Failed to create web service client:" + e );
    }catch( UnrecoverableKeyException e ){
      System.out.println( "Failed to create web service client:" + e );
    }catch( NoSuchAlgorithmException e ){
      System.out.println( "Failed to create web service client:" + e );
    }

  }

  private Key getPrivateKey( String keyname, String password, 
      String keystore) throws IOException, KeyStoreException, 
      NoSuchAlgorithmException, CertificateException,
      UnrecoverableKeyException{

    KeyStore ks = KeyStore.getInstance("JKS");
    ks.load(new FileInputStream(keystore), KEYSTORE_PASS.toCharArray());
    Key result = ks.getKey(keyname, password.toCharArray());
    return result;
  } 

  private static X509Certificate getCertificate(String keyname, 
      String keystore) throws IOException, KeyStoreException, NoSuchAlgorithmException, CertificateException {

    KeyStore ks = KeyStore.getInstance("JKS");
    ks.load(new FileInputStream(keystore), KEYSTORE_PASS.toCharArray());
    X509Certificate result = (X509Certificate) ks.getCertificate(keyname);
    return result;
  } 

  private static Key getPublicKey(String keyname, String keystore) 
      throws IOException, KeyStoreException, NoSuchAlgorithmException, 
      CertificateException {

    KeyStore ks = KeyStore.getInstance("JKS");

    ks.load(new FileInputStream(keystore), KEYSTORE_PASS.toCharArray());

    X509Certificate cert = (X509Certificate) ks.getCertificate(keyname);

    if (cert != null) {
      return cert.getPublicKey();
    } 

    return null;
  } 

}

