package com.gaowj.util;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.naming.Context;
import javax.naming.NameClassPair;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.ModificationItem;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;

import com.gaowj.business.util.PropUtil;


public class LdapImpl implements Ldap {
	private DirContext ds;

	//查询，可以查询多个值
		@Override
		public String search(String searchFilter, String searchBase, String returnedAtts[]) throws NamingException {
			System.out.println("Searching...");
			SearchControls searchCtls = new SearchControls();

			// Specify the search scope
			searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
		
			searchCtls.setReturningAttributes(returnedAtts);

			// Search for objects using the filter
			NamingEnumeration<SearchResult> entries = ds.search(searchBase,
					searchFilter, searchCtls);

			// Loop through the search results
			while (entries.hasMoreElements()) {
				SearchResult entry = entries.next();
				System.out.println(">>>" + entry.getName());
				// Print out the groups
				Attributes attrs = entry.getAttributes();
				if (attrs != null) {
					for (NamingEnumeration<? extends Attribute> names = attrs
							.getAll(); names.hasMore();) {
						Attribute attr = names.next();
						System.out.println("AttributeID: " + attr.getID());
						for (NamingEnumeration<?> e = attr.getAll(); e.hasMore();) {
							System.out.println("Attributes:" + e.next());
						}
					}
				}
				return entry.getName();
			}
			System.out.println("Search complete.");
			return null;
		}
	
	//查询节点信息
	
	public Map<String, Object> searchInfo(String searchFilter, String searchBase, String returnedAtts[]) throws NamingException {
		System.out.println("Searching...");
		SearchControls searchCtls = new SearchControls();

		// Specify the search scope
		searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
	
		searchCtls.setReturningAttributes(returnedAtts);

		// Search for objects using the filter
		NamingEnumeration<SearchResult> entries = ds.search(searchBase,
				searchFilter, searchCtls);

		// Loop through the search results
		while (entries.hasMoreElements()) {
			SearchResult entry = entries.next();
			System.out.println(">>>" + entry.getName());
			// Print out the groups
			Attributes attrs = entry.getAttributes();
			if (attrs != null) {
				for (NamingEnumeration<? extends Attribute> names = attrs
						.getAll(); names.hasMore();) {
					Attribute attr = names.next();
					System.out.println("AttributeID: " + attr.getID());
					for (NamingEnumeration<?> e = attr.getAll(); e.hasMore();) {
						System.out.println("Attributes:" + e.next());
					}
				}
			}
			
		}
		System.out.println("Search complete.");
		return null;
	}
	
	//ȫ����ѯ
	@Override
	public List<Map<String, Object>> searchAll(String searchFilter, String searchBase, String returnedAtts[]) throws NamingException{
		System.out.println("Searching...");
		SearchControls searchCtls = new SearchControls();
		searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
		NamingEnumeration<SearchResult> entries = ds.search(searchBase, searchFilter, searchCtls);
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		while (entries.hasMoreElements()){
			SearchResult entry = entries.next();
			//System.out.println(">>>" + entry.getName());
			Attributes attrs = entry.getAttributes();
			Map<String, Object> map = new HashMap<String, Object>();
			if (attrs != null) {
				for (NamingEnumeration<? extends Attribute> names = attrs
						.getAll(); names.hasMore();) {
					Attribute attr = names.next();
					//String user = names.next().toString();
					//System.out.println("AttributeID: " + attr.getID().toString());
					for (NamingEnumeration<?> e = attr.getAll(); e.hasMore();) {
						map.put(attr.getID(), e.next());
						//System.out.println("Attributes:" + e.next().toString());
					}
				}
			}
			map.put("rdn", entry.getName());
			list.add(map);
		}
		System.out.println("Search complete.");
		return list;
	}

	//����
	@Override
	public void update(String rdn, String key, Object value) throws NamingException {
		System.out.println("Updating...");
		 ModificationItem[] mods = new ModificationItem[1];
         Attribute attr = new BasicAttribute(key, value);
         // Support add, replace and remove an attribute.
         mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, attr);
         ds.modifyAttributes(rdn, mods);
		System.out.println("Updated.");
	}

	//���
	@Override
	public void add(String rdn, Attributes attrs) throws NamingException {
		System.out.println("Adding...");
		Attributes attributes = attrs;
		this.ds.createSubcontext(rdn, attributes);
		System.out.println("Add complete.");
	}

	//ɾ��
	@Override
	public void delete(String rdn) throws NamingException {
		System.out.println("Deleting...");
		this.ds.destroySubcontext(rdn);
		System.out.println("Deleted.");
	}
	
	//全量删除
	@Override
	public void ldapAllSubContext(String name, String rootNode) throws NamingException {
        String cn2 = "";
        String cn = name + "," + rootNode;
        NamingEnumeration<?> namingEnumeration = ds.list(cn);
        while (namingEnumeration.hasMore()) {
        NameClassPair nameClassPair = (NameClassPair) namingEnumeration.next();
        String na = nameClassPair.getName();
        cn2 = na + "," + name;
        ldapAllSubContext(cn2, rootNode);//递归调用
         try {
                      ds.destroySubcontext(cn2+","+rootNode);
                      System.out.println("删除："+ cn2 + "," + rootNode);

              } catch (NamingException e) {
                          e.printStackTrace();
             }
        }
     }

	//����
	@Override
	public synchronized void connect() throws NamingException {
		System.out.println("connecting...");
		Hashtable<String, Object> env = new Hashtable<String, Object>(11);
		env.put(Context.INITIAL_CONTEXT_FACTORY,  PropUtil.getValue("driver","quartz_service","com.sun.jndi.ldap.LdapCtxFactory"));
		env.put(Context.PROVIDER_URL, PropUtil.getValue("url","quartz_service","ldap://localhost:389"));
		env.put(Context.SECURITY_AUTHENTICATION, PropUtil.getValue("type","quartz_service","simple"));
		env.put(Context.SECURITY_PRINCIPAL, PropUtil.getValue("admin","quartz_service","cn=manager,dc=sky,dc=org"));
		env.put(Context.SECURITY_CREDENTIALS, PropUtil.getValue("password","quartz_service","secret"));
		ds = new InitialDirContext(env);
		System.out.println("connected.");
	}

	@Override
	public void close() throws NamingException {
		System.out.println("closing...");
		ds.close();
		System.out.println("closed.");
	}
	
	//��ȡ�ļ�
	public static Properties readConfig() {

		 Properties props =new Properties();
		 try {
			 //D:/workspace/ldap-operate/src/ldap.properties
			props.load(new FileInputStream("D:/workspace2/jwmagicIdentity/src_jwapp/com/jw/app/ldap/utils/ldap.properties"));
			//return props;
		} catch (FileNotFoundException e) {
			System.out.println("�����ļ�δ�ҵ�");
			e.printStackTrace();
		} catch (IOException e) {
			System.out.println("��ȡ����");
			e.printStackTrace();
		}
		  return props;
		}

}