package com.softbank.payapp.util;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.net.InetAddress;
import java.net.Socket;
import java.net.URI;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.util.HashMap;
import java.util.Map;

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

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.params.CoreConnectionPNames;

import com.landicorp.robert.comm.util.StringUtil;
import com.softbank.payapp.MainActivity;

import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Environment;


 
public class HttpsAuthentication extends SSLSocketFactory {

    SSLContext sslContext = SSLContext.getInstance("TLS");
    
    public HttpsAuthentication(KeyStore truststore, KeyManager[] key, TrustManager[] trust) throws NoSuchAlgorithmException,
            KeyManagementException, KeyStoreException, UnrecoverableKeyException {
        super(truststore);
        // set up a TrustManager that trusts everything
   	    javax.net.ssl.TrustManager tm = new miTM();
   	    trust[0] = tm;
        sslContext.init(key, trust, new java.security.SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
    }

    @Override
    public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
            throws IOException, UnknownHostException {
        injectHostname(socket, host);
        return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
    }

    @Override
    public Socket createSocket() throws IOException {
        return sslContext.getSocketFactory().createSocket();
    }
    
    private void injectHostname(Socket socket, String host) {
        try {
            Field field = InetAddress.class.getDeclaredField("hostName");
            field.setAccessible(true);
            field.set(socket.getInetAddress(), host);
        } catch (Exception ignored) {
        }
    }
  	 static class miTM implements javax.net.ssl.TrustManager,
	 javax.net.ssl.X509TrustManager {
	 public java.security.cert.X509Certificate[] getAcceptedIssuers() {
	 return null;
	 }

	 public boolean isServerTrusted(
	 java.security.cert.X509Certificate[] certs) {
	 return true;
	 }

	 public boolean isClientTrusted(
	 java.security.cert.X509Certificate[] certs) {
	 return true;
	 }

	 public void checkServerTrusted(
	 java.security.cert.X509Certificate[] certs, String authType)
	 throws java.security.cert.CertificateException {
	 return;
	 }

	 public void checkClientTrusted(
	 java.security.cert.X509Certificate[] certs, String authType)
	 throws java.security.cert.CertificateException {
	 return;
	 }
  	 }
  	 
  	 public static Map<String,Map> httpsConnect(Context context, String url, int clientCertificates, String clientCertificatesPwd, 
  			 int serverCertificates, String serverCertificatesPwd, boolean isPost ){
  		HttpResponse response = null;
  		Map<String,Map> map3 = new HashMap<String, Map>();
  		try{
	    	InputStream clientis = context.getResources().openRawResource(clientCertificates);
	    	InputStream serveris = context.getResources().openRawResource(serverCertificates);
	        KeyStore keyKeyStore  = KeyStore.getInstance("PKCS12","BC");
	        KeyStore trustKeyStore  = KeyStore.getInstance("PKCS12","BC");
	        keyKeyStore.load(clientis, clientCertificatesPwd.toCharArray());
	        clientis.close();
	    	trustKeyStore.load(serveris, serverCertificatesPwd.toCharArray());
	    	serveris.close();
			KeyManagerFactory keyManager = KeyManagerFactory.getInstance("X509");
			TrustManagerFactory trustManager = TrustManagerFactory.getInstance("X509");
			keyManager.init(keyKeyStore, clientCertificatesPwd.toCharArray());
			trustManager.init(trustKeyStore);
			HttpsAuthentication socketFactory = new HttpsAuthentication(trustKeyStore,keyManager.getKeyManagers(),
					trustManager.getTrustManagers());
			Scheme sch = new Scheme("https", socketFactory, 443);
		    HttpClient mHttpClient = Help.getNewHttpClient();
		    mHttpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 30000); 
		    mHttpClient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 30000); 
		    mHttpClient.getConnectionManager().getSchemeRegistry().register(sch);
		    if(false == isPost){
			    HttpGet request = new HttpGet();
			    request.setURI(new URI(url));
			    response = mHttpClient.execute(request);
		        if (response.getStatusLine().getStatusCode() != 200) {
		            request.abort();
		        }
		    }else{
		        HttpPost request = new HttpPost();
		        request.setURI(new URI(url));
		        response = mHttpClient.execute(request);
		        if (response.getStatusLine().getStatusCode() != 200) {
		            request.abort();
		        }
		    }
	        //response.getEntity().getContent();
	        Map<String, InputStream> map = new HashMap<String, InputStream>();
	        Map<String, String> map2 = new HashMap<String, String>();
	        map.put("inputStream", response.getEntity().getContent());
	        map2.put("length", String.valueOf(response.getEntity().getContentLength()));
	        map3.put("streamMap", map);
	        map3.put("lengthMap", map2);
	        
  		}catch(Exception e){
  			System.out.println(e);
  		}
  		return map3;
  	 }
  	 
  	 public static Map<String,Map> httpsConnect(Context context, byte[] params , String url, int clientCertificates, String clientCertificatesPwd, 
  			 int serverCertificates, String serverCertificatesPwd, String timeout){
  		HttpResponse response = null;
  		Map<String,Map> map3 = new HashMap<String, Map>();
  		try{
	    	InputStream clientis = context.getResources().openRawResource(clientCertificates);
	    	InputStream serveris = context.getResources().openRawResource(serverCertificates);
	        KeyStore keyKeyStore  = KeyStore.getInstance("PKCS12","BC");
	        KeyStore trustKeyStore  = KeyStore.getInstance("PKCS12","BC");
	        keyKeyStore.load(clientis, clientCertificatesPwd.toCharArray());
	        clientis.close();
	    	trustKeyStore.load(serveris, serverCertificatesPwd.toCharArray());
	    	serveris.close();
			KeyManagerFactory keyManager = KeyManagerFactory.getInstance("X509");
			TrustManagerFactory trustManager = TrustManagerFactory.getInstance("X509");
			keyManager.init(keyKeyStore, clientCertificatesPwd.toCharArray());
			trustManager.init(trustKeyStore);
			HttpsAuthentication socketFactory = new HttpsAuthentication(trustKeyStore,keyManager.getKeyManagers(),
					trustManager.getTrustManagers());
			Scheme sch = new Scheme("https", socketFactory, 443);
		    HttpClient mHttpClient = Help.getNewHttpClient();
		    mHttpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, Integer.parseInt(timeout+"000")); 
		    mHttpClient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, Integer.parseInt(timeout+"000")); 
		    mHttpClient.getConnectionManager().getSchemeRegistry().register(sch);
		    HttpPost request = new HttpPost();
	        request.setURI(new URI("https://"+url));
	        String channel = "gasas";
	        SharedPreferences preferences = context.getSharedPreferences("session", Activity.MODE_PRIVATE);
	        if(null != preferences && !StringUtil.isEmpty(preferences.getString("channel", ""))){
	        	channel = preferences.getString("channel", "");
	        }
	        request.addHeader("HOST","bftsas");
	        //request.addHeader("HOST","unionpay");
            request.addHeader("Content-Type","application/octet-stream");
            HttpEntity body = new ByteArrayEntity(params);
            request.setEntity(body);
	        response = mHttpClient.execute(request);
	        if (response.getStatusLine().getStatusCode() != 200) {
	            request.abort();
	        }
	        Map<String, InputStream> map = new HashMap<String, InputStream>();
	        Map<String, String> map2 = new HashMap<String, String>();
	        map.put("inputStream", response.getEntity().getContent());
	        map2.put("length", String.valueOf(response.getEntity().getContentLength()));
	        map3.put("streamMap", map);
	        map3.put("lengthMap", map2);
	        
  		}catch(Exception e){
  			System.out.println(e);
  		}
  		return map3;
  	 }  	 
  	 
  	 public static void downFile(Context context, InputStream is, String fileName){
  		 try{
  	  		BufferedInputStream bis = new BufferedInputStream(is);
  	  		
  	  		FileOutputStream fileOutputStream = null;
  	        if(is != null){
  	        	File file = new File(Environment.getExternalStorageDirectory(),fileName);
  	        	fileOutputStream = new FileOutputStream(file);
  	        	byte[] b = new byte[1024];
  	            int charb;
  	            int count = 0;
  	            while((charb = bis.read(b))!=-1){
  	                fileOutputStream.write(b, 0, charb);
  	                count += charb;
  	            }
  	        }
  	        fileOutputStream.flush();
  	        fileOutputStream.close();
  	        bis.close();
  	        is.close();
  		 }catch(Exception e){
   			try {
 				throw new Exception("更新失败,请检查网络");
 			} catch (Exception e1) {
 				// TODO Auto-generated catch block
 				e1.printStackTrace();
 			}
  		 }
  		
  	 }
  	 

}