package com.nms.server.util;

import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.nms.server.common.Constants;
import com.zhtelecom.common.base.MyException;
import com.zhtelecom.common.snmp.SNMPAPI;
import com.zhtelecom.common.snmp.SNMPFactory;
import com.zhtelecom.common.snmp.SNMPTarget;
import com.zhtelecom.common.snmp.impl.SNMPAPIImpl;
import com.zhtelecom.common.snmp.mib.MibIP;
import com.zhtelecom.mib.MibValueSymbol;

public class SNMPObjectUtils {
	private static Logger logger = Logger.getLogger(SNMPObjectUtils.class);
    public static final String ROOT="WALK";
    private static final Integer C_P_RETRIES=0;
    private static final Integer C_P_TIME_OUT=3000;
    private static final String C_P_COMMUNITY="public";
    private static final  int C_P_VERSION = SNMPTarget.VERSION2C;
    private static final SNMPAPI snmpapi = createSnmp();
    public SNMPObjectUtils() {
       
    }
    
    public static void snmpGetObject(List<Map<String,String>> datasMapList,String host,int port,String community,int retries,int timeout,int version,Class c) throws Exception{
    	
    	SNMPTarget target = createCommunityTarget(host,port,community,timeout, version);
		
    	try {
			snmpGetObject(datasMapList,snmpapi,target,c);
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
//			snmpapi.
		}
    }
    
//    public static void snmpGet(Map<String,String> datas,String[] oids,String host,String port,String community,int retries,int timeout,int version) throws Exception{
//    	SNMPAPI snmpapi = createSnmp(SNMPFactory.Mode_Local,"10.0.6.113",0,null);
//    	
//    	SNMPTarget target = createCommunityTarget(host,Integer.parseInt(port),community,timeout, version);
//        try {
//        	snmpGet(datas,oids,snmp,target);
//		} catch (Exception e) {
//			e.printStackTrace();
//		}finally{
//			snmp.close();
//		}
//    }
    
//    public static void snmpWalk(Map<String,String> datas,String oid,String host,String port,String community,int retries,int timeout,int version,String type) throws Exception{
//    	
//    	SNMPAPI snmpapi = createSnmp(SNMPFactory.Mode_Local,"10.0.6.113",0,null);
//    	
//    	SNMPTarget target = createCommunityTarget(host,Integer.parseInt(port),community,timeout, version);
//        try {
////			snmpGet(datas,oid,snmp,target);
//			snmpWalk(datas,new OID(oid),snmp,target,type);
//		} catch (Exception e) {
//			e.printStackTrace();
//		}finally{
//			snmp.close();
//		}
//    }
    
//    public static void snmpSet(String oid,String host,String port,String community,int retries,int timeout,int version,Variable newVar) throws Exception{
//    	
//    	SNMPAPI snmpapi = createSnmp(SNMPFactory.Mode_Local,"10.0.6.113",0,null);
//    	
//    	SNMPTarget target = createCommunityTarget(host,Integer.parseInt(port),community,timeout, version);
//        try {
//			snmpSet(new OID(oid),snmp,target,newVar);
//		} catch (Exception e) {
//			e.printStackTrace();
//		}finally{
//			snmp.close();
//		}
//    }
    
   
    /**
     * 
     * @param datas
     * @param oids
     * @param snmp
     * @param target
     * @throws Exception
     */
//    public static void snmpGet(Map<String,String> datas,String[] oids,SNMPAPI snmpapi,SNMPTarget target,Class c) throws Exception{
//       
//    	MibValueSymbol mibvaluesymbol = SNMPAPIImpl.getInstance().getMibSymbolByOid(oids);
//    	List list = snmpapi.getAllTableData(c, target); 
//    	
//    	
//    	for (int i = 0; i < list.size(); i++) 
//    	{ 
//    		ifTable table = (ifTable) list.get(i);
//    		Object obj= snmpapi.getMibObject(table,target); 
//    		System.out.println(obj); 
//    		System.out.println("第" + 0 + "个接口名称:" + table.genKey()); 
//    		System.out.println("第" + 0 + "个接口名称:" + table.getDbKey()); 
//    		System.out.println("第" + 0 + "个接口名称:" + table.getTableIndexOID()); 
//    		System.out.println("第" + i + "个接口名称:" + table.getIfDescr()); 
//    		System.out.println("第" + i + "个接口物理地址:" + table.getIfPhysAddress()); 
//    		System.out.println("第" + i + "个接口速度:" + table.getIfSpeed()); 
//    		System.out.println("第" + i + "个接口工作状态:" + table.getIfOperStatus()); 
//    	} 
//    	
//        PDU request = createPDU(PDU.GET);
//        for(String oid :oids ){
//            if((oid.toString()).endsWith(".0"))
//                request.add(new VariableBinding(new OID(oid)));
//            else{
//                throw new Exception(oid+" 为非基本节点");
//            }
//        }
//        ResponseEvent respEvent = snmp.send(request, target);
//        PDU response = respEvent.getResponse();
//        if(isNullPDU(response,"SNMP4J 响应结果为空")){
//        	return;
//        }
//        if(response.getErrorIndex()==PDU.noError&&response.getErrorStatus()==PDU.noError){
//            Vector<VariableBinding> vector = (Vector<VariableBinding>) response.getVariableBindings();
//            for(VariableBinding vb : vector){
//                String key = vb.getOid().toString();
//                datas.put(key,vb.getVariable().toString());   
//            }
//        }else{
//            throw new Exception("错误信息:"+response.getErrorStatusText());
//        }
//    }
   
    private static void pl(Object object){
    	System.out.println(object==null?null:object.toString());
    }
    private static void p(Object object){
    	System.out.print(object==null?null:object.toString());
    }
   /**
    * 
    * @param data
    * @param oid
    * @param snmp
    * @param target
    * @throws Exception
    */
    public static void snmpGetObject(List<Map<String,String>> datasMapList,SNMPAPI snmpapi,SNMPTarget target,Class c) throws Exception{
       
//    	if(StringUtils.isEmpty(oid)){
    		Object o = c.newInstance();
    		String oid = (String) c.getMethod("getMappingOID", null).invoke(o, null);
    		logger.debug("oid "+oid);
//    		if(oidObj!=null){
//    			oid = oidObj.toString();
//    		}
//    	}
//    	List<Map<String,String>> datasMapList = new LinkedList<Map<String,String>>();
    	//- 获取snmp get值
    	List objsList = snmpapi.getAllTableData(c, target);
    	pl("objsList size "+objsList.size());
    	//- 获取mib 树结构
    	MibValueSymbol mibvaluesymbol = SNMPAPIImpl.getInstance().getMibSymbolByOid(oid);
    	pl("oid "+oid);
        //- 结果解析
    	if(mibvaluesymbol !=null){
    		pl("mibvaluesymbol getChildren size "+mibvaluesymbol.getChildren().length);
			//- 获取所有子节点
			for (MibValueSymbol mibvaluekey : mibvaluesymbol.getChildren())
			{
				if (!mibvaluekey.isTable() && !mibvaluekey.isTableRow())
				{
					//字段名
					String filedName = mibvaluekey.getName();
					p("filedName "+filedName+" \t");
					//字段oid
					String childoid = mibvaluekey.getValue().toString();
					p("childoid "+childoid+" \t");
					//get方法存在标识
					boolean getFlag = true;

					if(objsList != null && objsList.size()>0){
						
						//-- 拼写规范的get方法名
						String methodName = "get"+Character.toUpperCase(filedName.charAt(0))+filedName.substring(1);
						p("methodName "+methodName+" \t");
						for (int i = 0; i < objsList.size(); i++) {
							Object obj = objsList.get(i);
							//--- 检查datasMap 是否存在  不存在创建
							Map<String,String> datas = datasMapList.size()>i?datasMapList.get(i):null;
							if(datas == null){
								datas = new HashMap<String, String>();
								datasMapList.add(datas);
							}
							
							//--- 填值
							if(getFlag){
								try {
									Object getValue = c.getMethod(methodName, null).invoke(obj, null);
									pl("getValue "+getValue+" \t");
									datas.put(childoid, getValue==null?null:getValue.toString());
								} catch (Exception e) {
									datas.put(childoid, null);
									getFlag = false;
									logger.warn("The method has not been found "+methodName);
								}
							}else{
								datas.put(childoid, null);
							}
						}
					}
					
				}
			}
    	}
    }
	public static void main(String[] args) {
		SNMPObjectUtils objectUtils = new SNMPObjectUtils();
		List<Map<String, String>> datasMapList = new LinkedList<Map<String,String>>();
		
//	//NMPObjectUtils.snmpGet(datasMapList, "", snmpapi, target, c);
		try {
			SNMPObjectUtils.snmpGetObject(datasMapList, "10.0.6.10", Constants.SNMP_CLIENT_PORT, Constants.SNMP_COMMUNITY, 3, 2000, SNMPTarget.VERSION2C, MibIP.class);
			System.out.println("--FF  "+datasMapList.size()); 
			for(Map<String, String> datas: datasMapList){
				
				
				System.out.println("-- "+Arrays.toString(datas.entrySet().toArray())); 
				System.out.println("-- "+MapUtils.toProperties(datas)); 
			}
		
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
//        test.testMibSystem();
//		
		//主动发现
//        DiscoverTest dTest = new DiscoverTest();
//        dTest.testPhysicsLink();
	}
    /**
     * 
     * @param datas
     * @param oid
     * @param snmp
     * @param target
     * @param type
     * @throws Exception
     */
//    public static void snmpWalk(Map<String,String> datas,OID oid,Snmp snmp,CommunityTarget target,String type) throws Exception{
//        if(type.equals(SNMP4JUtils.ROOT))
//            type= oid.toString();
//            PDU request = createPDU(PDU.GETNEXT);
//            request.add(new VariableBinding(oid));
//            ResponseEvent rspEvt = snmp.send(request, target);
//            PDU response = rspEvt.getResponse(); 	
//            if(isNullPDU(response,"")){
//            	return;
//            }
//            if(response.getErrorIndex()==PDU.noError&&response.getErrorStatus()==PDU.noError){
//                VariableBinding vb = (VariableBinding) response.getVariableBindings().firstElement();
//                OID curr_oid = vb.getOid();
//                String curr_str = curr_oid.toString();
//                if(curr_str.contains(type)){//判断获得的值是否是指定根节点下面
//                    String key = vb.getOid().toString();
//                    datas.put(key.replace(type, ""), vb.getVariable().toString());
//                    System.out.println("snmpWalkKey:"+key+":"+vb.getVariable().toString());
//                    if(!(vb.getVariable().toString()).equals("endOfMibView")){
//                    	snmpWalk(datas,curr_oid, snmp, target,type);
//                    }
//                }
//            }else{
//                throw new Exception("错误信息:"+response.getErrorStatusText());
//            }
//    }
    
   
//    public static void snmpSet(OID oid,Snmp snmp ,CommunityTarget target,Variable newVar) throws Exception{
//        PDU request = createPDU(PDU.SET);
//        request.add(new VariableBinding(oid,newVar));
//        ResponseEvent resEvt = snmp.send(request, target);
//        PDU response = resEvt.getResponse();
//        if(isNullPDU(response,"")){
//        	return;
//        }
//        if(response.getErrorIndex()==PDU.noError&&response.getErrorStatus()==PDU.noError){//判断返回报文是否正确
//            VariableBinding vb = (VariableBinding) response.getVariableBindings().firstElement();
//            Variable var = vb.getVariable();
//            if(var.equals(newVar)){//比较返回值和设置值
//                System.out.println("SET操作成功 ！");
//            }else{
//                System.out.println("SET操作失败 ！");
//            }
//        }else{
//            throw new Exception("错误信息:"+response.getErrorStatusText());
//        }
//    }
   
   
    public static SNMPTarget createCommunityTarget(String host,int port,String community,int timeout,int version){

    	SNMPTarget target = new SNMPTarget();
        target.nodeIP = host; //SNMP Agent代理地址
        target.port = port;
        target.readCommunity = StringUtils.isEmpty(community)?C_P_COMMUNITY:community; //SNMP读共同体

        target.snmpVersion = version==0?C_P_VERSION : version;
        logger.debug("-------target------------------"+target.nodeIP +" "+ target.readCommunity);
        return target;
    }
   
   
    public static SNMPAPI createSnmp() {
    	int mode = SNMPFactory.Mode_Local;
    	String ip = null;
    	int port = 0;
    	List<String> midList = null;
        //初始化ObjectSNMP模块,使用本地模式。 
    	SNMPAPI snmpapi = null;
        try {
        	//初始化 SNMP工厂
			SNMPFactory.init(mode,ip,port);
			
			//- 载入mib库
			if(midList != null && midList.size()>0){
				for(String str : midList){
					SNMPFactory.loadMib(str); 
				}
			}
			// 获取SNMP API 
			snmpapi = SNMPFactory.getSNMPAPI();
		} catch (MyException e) {
			logger.error("", e);
		} 

        return snmpapi;
    }
 /*  
   
    private static PDU createPDU(int type){
        PDU pdu= new PDU();
        pdu.setType(type);
        return pdu;
    }
    *//**
     * PDU为空判断
     * @param pdu 需判断的PDU
     * @param messages PDU为空是输出的提示信息
     * @return
     * @throws Exception 
     *//*
    public static boolean isNullPDU(PDU pdu, String messages) throws Exception{
    	boolean isNull = true;
    	if(pdu!=null){
    		isNull = false;
    	}else{
    		isNull = true;
    		//pdu为空的处理可以添加到这里
    		logger.debug(messages);
    		throw new Exception("错误信息:"+messages);
    	}
    	return isNull;
    }
*/
}
