package com.yifu.cloud.plus.v1.yifu.common.ldap.util;

import com.unboundid.ldap.sdk.*;
import com.unboundid.ldap.sdk.controls.SubentriesRequestControl;
import com.unboundid.util.Base64;
import com.yifu.cloud.plus.v1.yifu.common.ldap.config.LdapProperties;
import com.yifu.cloud.plus.v1.yifu.common.ldap.entity.PersonVo;
import com.yifu.cloud.plus.v1.yifu.common.ldap.mapper.PersonAttributesMapper;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.ldap.core.LdapTemplate;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;

import static org.springframework.ldap.query.LdapQueryBuilder.query;

@Log4j2
@EnableConfigurationProperties(LdapProperties.class)
public class LdapUtil {

	@Autowired
	private LdapTemplate ldapTemplate;

	@Autowired
	private LdapProperties ldapProperties;

	/**
	 * @return List<SearchResultEntry>
	 * @author huyc
	 * @date 2022-06-14 17:56
	 * @description get请求获取指定对象信息
	 **/
	public List<SearchResultEntry> getAllPersonNamesWithTraditionalWay() {
		List<SearchResultEntry> result = new ArrayList<>();
		try (LDAPConnection connection = new LDAPConnection(ldapProperties.getUrl(), ldapProperties.getPort(),
				ldapProperties.getUserName(), ldapProperties.getPassword())) {
			SearchRequest searchRequest = new SearchRequest(ldapProperties.getBaseDn(), SearchScope.SUB,
					"(objectclass=*)");
			searchRequest.addControl(new SubentriesRequestControl());
			SearchResult searchResult = connection.search(searchRequest);
			result.addAll(searchResult.getSearchEntries());
		} catch (LDAPException e) {
			e.printStackTrace();
		}
		return result;
	}

	public List<PersonVo> getAllPersons() {
		return ldapTemplate.search(query()
				.where("objectclass").is("posixAccount"), new PersonAttributesMapper());
	}

	// 校验用户名密码的方法
	public Boolean authenticate(String usr, String pwd) throws NoSuchAlgorithmException {
		if (pwd == null || "".equals(pwd))
			return false;
		try {
			List<SearchResultEntry> entryList = this.getAllPersonNamesWithTraditionalWay();
			byte[] ldapPw = new byte[0];
			for (SearchResultEntry resultEntry: entryList){
				if (resultEntry.getDN().contains("uid="+usr)) {
					String password = resultEntry.getAttributeValue("userPassword");
					if (null != password) {
						String ldapPwd1 = password.substring(5);
						ldapPw = Base64.decode(ldapPwd1);
						break;
					} else {
						return false;
					}
				}
			}
			MessageDigest md5 = MessageDigest.getInstance("MD5");
			md5.update(pwd.getBytes());
			byte[] m = md5.digest();
			return MessageDigest.isEqual(m, ldapPw);
		} catch (ParseException e) {
			log.error(" is not authenticated");
		}
		return false;
	}
}
