/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License") +  you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.openmeetings.ldap;

import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_DEFAULT_GROUP_ID;
import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import org.apache.directory.api.ldap.model.cursor.CursorLdapReferralException;
import org.apache.directory.api.ldap.model.cursor.EntryCursor;
import org.apache.directory.api.ldap.model.entry.Attribute;
import org.apache.directory.api.ldap.model.entry.Entry;
import org.apache.directory.api.ldap.model.exception.LdapAuthenticationException;
import org.apache.directory.api.ldap.model.exception.LdapException;
import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeValueException;
import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException;
import org.apache.directory.api.ldap.model.message.AliasDerefMode;
import org.apache.directory.api.ldap.model.message.SearchRequestImpl;
import org.apache.directory.api.ldap.model.message.SearchScope;
import org.apache.directory.api.ldap.model.name.Dn;
import org.apache.directory.api.ldap.model.name.Rdn;
import org.apache.directory.ldap.client.api.EntryCursorImpl;
import org.apache.directory.ldap.client.api.LdapConnection;
import org.apache.directory.ldap.client.api.LdapNetworkConnection;
import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
import org.apache.openmeetings.db.dao.server.LdapConfigDao;
import org.apache.openmeetings.db.dao.user.OrganisationDao;
import org.apache.openmeetings.db.dao.user.StateDao;
import org.apache.openmeetings.db.dao.user.UserDao;
import org.apache.openmeetings.db.entity.server.LdapConfig;
import org.apache.openmeetings.db.entity.user.Organisation;
import org.apache.openmeetings.db.entity.user.Organisation_Users;
import org.apache.openmeetings.db.entity.user.User;
import org.apache.openmeetings.db.entity.user.User.Right;
import org.apache.openmeetings.db.entity.user.User.Type;
import org.apache.openmeetings.db.util.TimezoneUtil;
import org.apache.openmeetings.util.OmException;
import org.apache.openmeetings.util.OmFileHelper;
import org.apache.wicket.util.string.Strings;
import org.red5.logging.Red5LoggerFactory;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * Management of optional LDAP Login
 * 
 * @author o.becherer
 * 
 */
public class LdapLoginManagement {
	private static final Logger log = Red5LoggerFactory.getLogger(LdapLoginManagement.class, webAppRootKey);
	// Config constants
	private static final String CONFIGKEY_LDAP_HOST = "ldap_conn_host";
	private static final String CONFIGKEY_LDAP_PORT = "ldap_conn_port";
	private static final String CONFIGKEY_LDAP_SECURE = "ldap_conn_secure";
	private static final String CONFIGKEY_LDAP_ADMIN_DN = "ldap_admin_dn";
	private static final String CONFIGKEY_LDAP_ADMIN_PASSWD = "ldap_passwd";
	private static final String CONFIGKEY_LDAP_AUTH_TYPE = "ldap_auth_type";
	private static final String CONFIGKEY_LDAP_PROV_TYPE = "ldap_provisionning";

	private static final String CONFIGKEY_LDAP_SYNC_PASSWD_OM = "ldap_sync_password_to_om"; // 'true' or 'false'
	private static final String CONFIGKEY_LDAP_USE_LOWER_CASE = "ldap_use_lower_case";
	private static final String CONFIGKEY_LDAP_TIMEZONE_NAME = "ldap_user_timezone";
	private static final String CONFIGKEY_LDAP_SEARCH_BASE = "ldap_search_base";
	private static final String CONFIGKEY_LDAP_SEARCH_QUERY = "ldap_search_query";
	private static final String CONFIGKEY_LDAP_SEARCH_SCOPE = "ldap_search_scope";
	private static final String CONFIGKEY_LDAP_USERDN_FORMAT = "ldap_userdn_format";
	private static final String CONFIGKEY_LDAP_USE_ADMIN_4ATTRS = "ldap_use_admin_to_get_attrs";
	private static final String CONFIGKEY_LDAP_DEREF_MODE = "ldap_deref_mode";
	private static final String CONFIGKEY_LDAP_GROUP_MODE = "ldap_group_mode";
	private static final String CONFIGKEY_LDAP_GROUP_QUERY = "ldap_group_query";
	
	// LDAP custom attribute mapping keys
	private static final String CONFIGKEY_LDAP_KEY_LASTNAME = "ldap_user_attr_lastname";
	private static final String CONFIGKEY_LDAP_KEY_FIRSTNAME = "ldap_user_attr_firstname";
	private static final String CONFIGKEY_LDAP_KEY_MAIL = "ldap_user_attr_mail";
	private static final String CONFIGKEY_LDAP_KEY_STREET = "ldap_user_attr_street";
	private static final String CONFIGKEY_LDAP_KEY_ADDITIONAL_NAME = "ldap_user_attr_additionalname";
	private static final String CONFIGKEY_LDAP_KEY_FAX = "ldap_user_attr_fax";
	private static final String CONFIGKEY_LDAP_KEY_ZIP = "ldap_user_attr_zip";
	private static final String CONFIGKEY_LDAP_KEY_COUNTRY = "ldap_user_attr_country";
	private static final String CONFIGKEY_LDAP_KEY_TOWN = "ldap_user_attr_town";
	private static final String CONFIGKEY_LDAP_KEY_PHONE = "ldap_user_attr_phone";
	private static final String CONFIGKEY_LDAP_KEY_PICTURE_URI = "ldap_user_picture_uri";
	private static final String CONFIGKEY_LDAP_KEY_GROUP = "ldap_group_attr";

	// LDAP default attributes mapping
	private static final String LDAP_KEY_LASTNAME = "sn";
	private static final String LDAP_KEY_FIRSTNAME = "givenName";
	private static final String LDAP_KEY_MAIL = "mail";
	private static final String LDAP_KEY_STREET = "streetAddress";
	private static final String LDAP_KEY_ADDITIONAL_NAME = "description";
	private static final String LDAP_KEY_FAX = "facsimileTelephoneNumber";
	private static final String LDAP_KEY_ZIP = "postalCode";
	private static final String LDAP_KEY_COUNTRY = "co";
	private static final String LDAP_KEY_TOWN = "l";
	private static final String LDAP_KEY_PHONE = "telephoneNumber";
	private static final String LDAP_KEY_TIMEZONE = "timezone";
	private static final String LDAP_KEY_PICTURE_URI = "pictureUri";
	private static final String LDAP_KEY_GROUP = "memberOf";

	public enum AuthType {
		NONE
		, SEARCHANDBIND
		, SIMPLEBIND
	}
	
	public enum Provisionning {
		NONE
		, AUTOUPDATE
		, AUTOCREATE
	}
	
	public enum GroupMode {
		NONE
		, ATTRIBUTE
		, QUERY
	}
	
	@Autowired
	private ConfigurationDao cfgDao;
	@Autowired
	private StateDao stateDao;
	@Autowired
	private LdapConfigDao ldapConfigDao;
	@Autowired
	private UserDao userDao;
	@Autowired
	private OrganisationDao orgDao;
	@Autowired
	private TimezoneUtil timezoneUtil;

	private Dn getUserDn(Properties config, String user) throws LdapInvalidDnException {
		return new Dn(String.format(config.getProperty(CONFIGKEY_LDAP_USERDN_FORMAT, "%s"), user));
	}
	
	private void bindAdmin(LdapConnection conn, String admin, String pass) throws LdapException {
		if (!Strings.isEmpty(admin)) {
			conn.bind(admin, pass);
		} else {
			conn.bind();
		}
	}
	
	private String getAttr(Properties config, Entry entry, String aliasCode, String defaultAlias) throws LdapInvalidAttributeValueException {
		String alias = config.getProperty(aliasCode, "");
		Attribute a = entry.get(Strings.isEmpty(alias) ? defaultAlias : alias);
		return a == null ? null : a.getString();
	}
	/**
	 * Ldap Login
	 * 
	 * Connection Data is retrieved from ConfigurationFile
	 * 
	 */
	// ----------------------------------------------------------------------------------------
	public User login(String login, String passwd, Long domainId) throws OmException {
		log.debug("LdapLoginmanagement.doLdapLogin");
		if (!userDao.validLogin(login)) {
			log.error("Invalid login provided");
			return null;
		}

		Properties config = new Properties();
		Reader r = null;
		try {
			LdapConfig ldapConfig = ldapConfigDao.get(domainId);
			r = new InputStreamReader(new FileInputStream(new File(OmFileHelper.getConfDir(), ldapConfig.getConfigFileName())), "UTF-8");
			config.load(r);
		} catch (Exception e) {
			log.error("Error on LdapLogin : Configurationdata couldn't be retrieved!");
			return null;
		} finally {
			if (r != null) {
				try {
					r.close();
				} catch (IOException e) {
					log.error("Error while closing ldap config file");
					return null;
				}
			}
		}
		if (config.isEmpty()) {
			log.error("Error on LdapLogin : Configurationdata couldnt be retrieved!");
			return null;
		}

		String ldap_use_lower_case = config.getProperty(CONFIGKEY_LDAP_USE_LOWER_CASE, "false");
		if ("true".equals(ldap_use_lower_case)) {
			login = login.toLowerCase();
		}

		String ldap_auth_type = config.getProperty(CONFIGKEY_LDAP_AUTH_TYPE, "");
		AuthType type = AuthType.SIMPLEBIND;
		try {
			type = AuthType.valueOf(ldap_auth_type);
		} catch (Exception e) {
			log.error(String.format("ConfigKey in Ldap Config contains invalid auth type : '%s' -> Defaulting to %s", ldap_auth_type, type));
		}
		
		String ldap_prov_type = config.getProperty(CONFIGKEY_LDAP_PROV_TYPE, "");
		Provisionning prov = Provisionning.AUTOCREATE;
		try {
			prov = Provisionning.valueOf(ldap_prov_type);
		} catch (Exception e) {
			log.error(String.format("ConfigKey in Ldap Config contains invalid provisionning type : '%s' -> Defaulting to %s", ldap_prov_type, prov));
		}
		
		String ldap_deref_mode = config.getProperty(CONFIGKEY_LDAP_DEREF_MODE, "");
		AliasDerefMode derefMode = AliasDerefMode.DEREF_ALWAYS;
		try {
			derefMode = AliasDerefMode.getDerefMode(ldap_deref_mode);
		} catch (Exception e) {
			log.error(String.format("ConfigKey in Ldap Config contains invalid deref mode : '%s' -> Defaulting to %s", ldap_deref_mode, derefMode));
		}
		
		if (AuthType.NONE == type && Provisionning.NONE == prov) {
			log.error("Both AuthType and Provisionning are NONE!");
			return null;
		}
		boolean useAdminForAttrs = true;
		try {
			useAdminForAttrs = "true".equals(config.getProperty(CONFIGKEY_LDAP_USE_ADMIN_4ATTRS, ""));
		} catch (Exception e) {
			//no-op
		}
		GroupMode groupMode = GroupMode.NONE;
		try {
			groupMode = GroupMode.valueOf(config.getProperty(CONFIGKEY_LDAP_GROUP_MODE, "NONE"));
		} catch (Exception e) {
			//no-op
		}
		if (AuthType.NONE == type && !useAdminForAttrs) {
			log.error("Unable to get Attributes, please change Auth type and/or Use Admin to get attributes");
			return null;
		}

		// Connection URL
		String ldap_host = config.getProperty(CONFIGKEY_LDAP_HOST);
		int ldap_port = Integer.parseInt(config.getProperty(CONFIGKEY_LDAP_PORT, "389"));
		boolean ldap_secure = "true".equals(config.getProperty(CONFIGKEY_LDAP_SECURE, "false"));

		// Username for LDAP SERVER himself
		String ldap_admin_dn = config.getProperty(CONFIGKEY_LDAP_ADMIN_DN);

		// Password for LDAP SERVER himself
		String ldap_admin_passwd = config.getProperty(CONFIGKEY_LDAP_ADMIN_PASSWD);

		User u = null;
		LdapConnection conn = null;
		try {
			boolean authenticated = true;
			conn = new LdapNetworkConnection(ldap_host, ldap_port, ldap_secure);
			Dn userDn = null;
			Entry entry = null;
			switch (type) {
				case SEARCHANDBIND:
				{
					bindAdmin(conn, ldap_admin_dn, ldap_admin_passwd);
					Dn baseDn = new Dn(config.getProperty(CONFIGKEY_LDAP_SEARCH_BASE, ""));
					String searchQ = String.format(config.getProperty(CONFIGKEY_LDAP_SEARCH_QUERY, "%s"), login);
					SearchScope scope = SearchScope.valueOf(config.getProperty(CONFIGKEY_LDAP_SEARCH_SCOPE, SearchScope.ONELEVEL.name()));
			        
					EntryCursor cursor = new EntryCursorImpl(conn.search(
							new SearchRequestImpl()
								.setBase(baseDn)
								.setFilter(searchQ)
								.setScope(scope)
								.addAttributes("*")
								.setDerefAliases(derefMode)));
					while (cursor.next()) {
						try {
							Entry e = cursor.get();
							if (userDn != null) {
								log.error("more than 1 user found in LDAP");
								throw new OmException(-1L);
							}
							userDn = e.getDn();
							if (useAdminForAttrs) {
								entry = e;
							}
						} catch (CursorLdapReferralException cle) {
							log.warn("Referral LDAP entry found, ignore it");
						}
					}
					cursor.close();
					if (userDn == null) {
						log.error("NONE users found in LDAP");
						throw new OmException(-11L);
					}
					conn.bind(userDn, passwd);
				}
					break;
				case SIMPLEBIND:
				{
					userDn = getUserDn(config, login);
					conn.bind(userDn, passwd);
				}
					break;
				case NONE:
				default:
					authenticated = false;
					break;
			}
			u = authenticated ? userDao.getByLogin(login, Type.ldap, domainId) : userDao.login(login, passwd);
			if (u == null && Provisionning.AUTOCREATE != prov) {
				log.error("User not found in OM DB and Provisionning.AUTOCREATE was not set");
				throw new OmException(-11L);
			}
			if (authenticated && entry == null) {
				if (useAdminForAttrs) {
					bindAdmin(conn, ldap_admin_dn, ldap_admin_passwd);
				}
				entry = conn.lookup(userDn);
			}
			switch (prov) {
				case AUTOUPDATE:
				case AUTOCREATE:
					if (entry == null) {
						log.error("LDAP entry is null, search or lookup by Dn failed");
						throw new OmException(-11L);
					}
					if (u == null) {
						u = userDao.getNewUserInstance(null);
						u.setType(Type.ldap);
						u.getRights().remove(Right.Login);
						u.setDomainId(domainId);
						u.getOrganisation_users().add(new Organisation_Users(orgDao.get(cfgDao.getConfValue(CONFIG_DEFAULT_GROUP_ID, Long.class, "-1"))));
						u.setLogin(login);
						u.setShowContactDataToContacts(true);
					}
					if ("true".equals(config.getProperty(CONFIGKEY_LDAP_SYNC_PASSWD_OM, ""))) {
						u.updatePassword(cfgDao, passwd);
					}
					u.setLastname(getAttr(config, entry, CONFIGKEY_LDAP_KEY_LASTNAME, LDAP_KEY_LASTNAME));
					u.setFirstname(getAttr(config, entry, CONFIGKEY_LDAP_KEY_FIRSTNAME, LDAP_KEY_FIRSTNAME));
					u.getAdresses().setEmail(getAttr(config, entry, CONFIGKEY_LDAP_KEY_MAIL, LDAP_KEY_MAIL));
					u.getAdresses().setStreet(getAttr(config, entry, CONFIGKEY_LDAP_KEY_STREET, LDAP_KEY_STREET));
					u.getAdresses().setAdditionalname(getAttr(config, entry, CONFIGKEY_LDAP_KEY_ADDITIONAL_NAME, LDAP_KEY_ADDITIONAL_NAME));
					u.getAdresses().setFax(getAttr(config, entry, CONFIGKEY_LDAP_KEY_FAX, LDAP_KEY_FAX));
					u.getAdresses().setZip(getAttr(config, entry, CONFIGKEY_LDAP_KEY_ZIP, LDAP_KEY_ZIP));
					u.getAdresses().setStates(stateDao.getStateByName(getAttr(config, entry, CONFIGKEY_LDAP_KEY_COUNTRY, LDAP_KEY_COUNTRY)));
					u.getAdresses().setTown(getAttr(config, entry, CONFIGKEY_LDAP_KEY_TOWN, LDAP_KEY_TOWN));
					u.getAdresses().setPhone(getAttr(config, entry, CONFIGKEY_LDAP_KEY_PHONE, LDAP_KEY_PHONE));
					String tz = getAttr(config, entry, CONFIGKEY_LDAP_TIMEZONE_NAME, LDAP_KEY_TIMEZONE);
					if (tz == null) {
						tz = config.getProperty(CONFIGKEY_LDAP_TIMEZONE_NAME, null);
					}
					u.setTimeZoneId(timezoneUtil.getTimeZone(tz).getID());
					String picture = getAttr(config, entry, CONFIGKEY_LDAP_KEY_PICTURE_URI, LDAP_KEY_PICTURE_URI);
					if (picture == null) {
						picture = config.getProperty(CONFIGKEY_LDAP_KEY_PICTURE_URI, null);
					}
					u.setPictureuri(picture);
					
					u = userDao.update(u, null);
					
					List<Dn> groups = new ArrayList<>();
					if (GroupMode.ATTRIBUTE == groupMode) {
						Attribute a = entry.get(config.getProperty(CONFIGKEY_LDAP_KEY_GROUP, LDAP_KEY_GROUP));
						String attr = a == null ? "" : a.getString();
						for (String g : attr.split("|")) {
							groups.add(new Dn(g));
						}
					} else if (GroupMode.QUERY == groupMode) {
						Dn baseDn = new Dn(config.getProperty(CONFIGKEY_LDAP_SEARCH_BASE, ""));
						String searchQ = String.format(config.getProperty(CONFIGKEY_LDAP_GROUP_QUERY, "%s"), login);
				        
						EntryCursor cursor = new EntryCursorImpl(conn.search(
								new SearchRequestImpl()
									.setBase(baseDn)
									.setFilter(searchQ)
									.setScope(SearchScope.SUBTREE)
									.addAttributes("*")
									.setDerefAliases(AliasDerefMode.DEREF_ALWAYS)));
						while (cursor.next()) {
							try {
								Entry e = cursor.get();
								groups.add(e.getDn());
							} catch (CursorLdapReferralException cle) {
								log.warn("Referral LDAP entry found, ignore it");
							}
						}
						cursor.close();
					}
					for (Dn g : groups) {
						Rdn namer = g.getRdn();
						String name = namer.getValue().toString();
						if (!Strings.isEmpty(name)) {
							Organisation o = orgDao.get(name);
							boolean found = false;
							if (o == null) {
								o = new Organisation();
								o.setName(name);
								o = orgDao.update(o, u.getUser_id());
							} else {
								for (Organisation_Users ou : u.getOrganisation_users()) {
									if (ou.getOrganisation().getName().equals(name)) {
										found = true;
										break;
									}
								}
							}
							if (!found) {
								u.getOrganisation_users().add(new Organisation_Users(o));
								userDao.update(u, u.getUser_id());
								log.debug("Going to add user to group:: " + name);
							}
						}
					}
					break;
				case NONE:
				default:
					break;
			}
		} catch (LdapAuthenticationException ae) {
			log.error("Not authenticated.", ae);
			throw new OmException(-11L);
		} catch (OmException e) {
			throw e;
		} catch (Exception e) {
			log.error("Unexpected exception.", e);
			throw new OmException(e);
		} finally {
			if (conn != null) {
				try {
					conn.unBind();
					conn.close();
				} catch (Exception e) {
					log.error("Unexpected exception.", e);
					throw new OmException(e);
				}
			}
		}
		return u;
	}
}
