package com.fuzamei.util.blockchain;

import smsc.Api;

import java.lang.reflect.Method;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.SignatureException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.fuzamei.eddsa.EdDSAEngine;
import com.fuzamei.eddsa.EdDSAPrivateKey;
import com.fuzamei.eddsa.spec.EdDSANamedCurveTable;
import com.fuzamei.eddsa.spec.EdDSAParameterSpec;
import com.fuzamei.eddsa.spec.EdDSAPrivateKeySpec;
import com.fuzamei.util.ReadConfUtil;
import com.google.protobuf.ByteString;


/**
 * Created by zhengfan on 2017/7/17.
 * Explain
 */
public class ProtobufUtils {
	/**
	 * 
	* @Title: initPlatform
	* @Description: TODO 平台初始化---广发催收项目
	* @param @return
	* @return ProtobufBean
	* @author: Ma Amin
	* @date: 2017-11-16 下午2:37:39
	 */
	/*public static ProtobufBean initPlatform(){
		ProtobufBean protobufBean = new ProtobufBean();
		//取出最大公钥和私钥
		String pubkey = ReadConfUtil.getProperty("publicKey");	//平台最大的公钥
		String platformPrivateKey = "90b289fda1fb0439158f837bbe60cc1ec99616dd0bc6335d6fd0bf3d22888e20";	//平台公钥，随便弄一个
		String platformKey = ReadConfUtil.getProperty("privateKey");	//平台最大的私钥
		Api.RequestInitPlatform.Builder builder = Api.RequestInitPlatform.newBuilder();
		try {
        	builder.setPlatformKey(ByteString.copyFrom(HexUtil.hexString2Bytes(platformKey)));
        	builder.setInfo("平台初始化");
        	SecureRandom secureRandom = new SecureRandom();
            long instructionId = secureRandom.nextLong();	//随机数
            protobufBean.setInstructionId(instructionId);
            //将requestCreateAccount对象签名
            Api.RequestInitPlatform requestBuyServe = builder.build();
            //request携带请求信息
            Api.Request.Builder request = Api.Request.newBuilder();
            request.setInitPlatform(builder);
            request.setInstructionId(instructionId);
            request.setActionId(Api.MessageType.MsgInitPlatform);
            request.setPubkey(ByteString.copyFrom(HexUtil.hexString2Bytes(pubkey)));
            Api.Request request1 = request.build();
            //用操作者的私钥签名
            byte[] bytePrivateKey = HexUtil.hexString2Bytes(platformPrivateKey);
            //签名啊
            ByteString signByteString = getSign(request1.toByteArray(), bytePrivateKey);
            //签名后的结果也给request
            request.setSign(signByteString);
            //将携带着签名后的参数信息通过http给合约，在callback里解析
            Api.Request request2 = request.build();
            byte[] requestByte = request2.toByteArray();
//            String signdata = HexUtil.bytes2HexString(requestByte);
            String signdateBase64 = encodeBase64(requestByte);
            protobufBean.setSignature(signdateBase64);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return protobufBean;
	}*/
	public static ProtobufBean requestUserCreate(long userUid,String adminPubKey) {	//用户公钥，调用者的公钥
//    	String operatorPrivateKey = "90b289fda1fb0439158f837bbe60cc1ec99616dd0bc6335d6fd0bf3d22888e20";
        
		String platformPrivateKey = "90b289fda1fb0439158f837bbe60cc1ec99616dd0bc6335d6fd0bf3d22888e20"; 	//平台私钥
		String pubkey = "b15a4f6c5c1163b5f80715c9bd87d5118ec4b5668cb29f148eeceec61ddeadc2"; 				//平台公钥
		
		ProtobufBean protobufBean = new ProtobufBean();
        //创建 RequestUserCreate 对象，设置参数
        Api.RequestSetAdmin.Builder builder = Api.RequestSetAdmin.newBuilder();
        try {
//        	builder.setUserUid(userUid);
//        	builder.setUserName(userName);
        	builder.setPubkey(ByteString.copyFrom(HexUtil.hexString2Bytes(adminPubKey)));
        	SecureRandom secureRandom = new SecureRandom();
            long instructionId = secureRandom.nextLong();	//随机数
            protobufBean.setInstructionId(instructionId);
            //将requestCreateAccount对象签名
            Api.RequestSetAdmin requestBuyServe = builder.build();
            //request携带请求信息
            Api.Request.Builder request = Api.Request.newBuilder();
            request.setSetAdmin(builder);
            request.setInstructionId(instructionId);
            request.setActionId(Api.MessageType.MsgSetAdmin);
            request.setPubkey(ByteString.copyFrom(HexUtil.hexString2Bytes(pubkey)));
            request.setUid(userUid);
            Api.Request request1 = request.build();
//            用操作者的私钥签名
            byte[] bytePrivateKey = HexUtil.hexString2Bytes(platformPrivateKey);
            //签名啊
            ByteString signByteString = getSign(request1.toByteArray(), bytePrivateKey);
            //签名后的结果也给request
            request.setSign(signByteString);
            //将携带着签名后的参数信息通过http给合约，在callback里解析
            Api.Request request2 = request.build();
            byte[] requestByte = request2.toByteArray();
           // String signdata = HexUtil.bytes2HexString(requestByte);
            String signdateBase64 = encodeBase64(requestByte);
            protobufBean.setSignature(signdateBase64);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return protobufBean;
    }
   private static ByteString getSign(byte[] requestByte, byte[] bytePrivateKey) {
        EdDSAParameterSpec spec = EdDSANamedCurveTable.getByName("Ed25519");
        byte[] signbyte = new byte[0];
        try {
            Signature sgr = new EdDSAEngine(MessageDigest.getInstance(spec.getHashAlgorithm()));
            EdDSAPrivateKeySpec privKey = new EdDSAPrivateKeySpec(bytePrivateKey, spec);
            PrivateKey sKey = new EdDSAPrivateKey(privKey);
            sgr.initSign(sKey);
            sgr.update(requestByte);
            signbyte = sgr.sign();
        } catch (NoSuchAlgorithmException e) {
        	throw new RuntimeException(e);
        } catch (SignatureException e) {
        	throw new RuntimeException(e);
        } catch (InvalidKeyException e) {
        	throw new RuntimeException(e);
        }
        return ByteString.copyFrom(signbyte,0,64);
    }
    public static String encodeBase64(byte[]input) throws Exception{  
        Class clazz=Class.forName("com.sun.org.apache.xerces.internal.impl.dv.util.Base64");  
        Method mainMethod= clazz.getMethod("encode", byte[].class);  
        mainMethod.setAccessible(true);  
         Object retObj=mainMethod.invoke(null, new Object[]{input});  
         return (String)retObj;  
    }  

}

