/*
 * 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.web.app;

import static java.text.DateFormat.SHORT;
import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_DASHBOARD_SHOW_MYROOMS_KEY;
import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_DASHBOARD_SHOW_RSS_KEY;
import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_DEFAULT_LANG_KEY;
import static org.apache.openmeetings.web.app.Application.getAuthenticationStrategy;
import static org.apache.openmeetings.web.app.Application.getBean;
import static org.apache.openmeetings.web.app.Application.getClientByKeys;
import static org.apache.openmeetings.web.app.Application.getDashboardContext;
import static org.apache.openmeetings.web.app.Application.isInvaldSession;
import static org.apache.openmeetings.web.app.Application.removeInvalidSession;
import static org.apache.openmeetings.web.app.Application.removeOnlineUser;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.TimeZone;

import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
import org.apache.openmeetings.db.dao.label.LabelDao;
import org.apache.openmeetings.db.dao.server.SOAPLoginDao;
import org.apache.openmeetings.db.dao.server.SessiondataDao;
import org.apache.openmeetings.db.dao.user.IUserManager;
import org.apache.openmeetings.db.dao.user.UserDao;
import org.apache.openmeetings.db.entity.server.RemoteSessionObject;
import org.apache.openmeetings.db.entity.server.SOAPLogin;
import org.apache.openmeetings.db.entity.server.Sessiondata;
import org.apache.openmeetings.db.entity.user.State;
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.ldap.LdapLoginManagement;
import org.apache.openmeetings.util.OmException;
import org.apache.openmeetings.web.pages.SwfPage;
import org.apache.openmeetings.web.user.dashboard.MyRoomsWidget;
import org.apache.openmeetings.web.user.dashboard.MyRoomsWidgetDescriptor;
import org.apache.openmeetings.web.user.dashboard.RssWidget;
import org.apache.openmeetings.web.user.dashboard.RssWidgetDescriptor;
import org.apache.openmeetings.web.user.dashboard.StartWidgetDescriptor;
import org.apache.openmeetings.web.user.dashboard.WelcomeWidgetDescriptor;
import org.apache.openmeetings.web.util.OmUrlFragment;
import org.apache.openmeetings.web.util.UserDashboard;
import org.apache.wicket.RestartResponseAtInterceptPageException;
import org.apache.wicket.authentication.IAuthenticationStrategy;
import org.apache.wicket.authroles.authentication.AbstractAuthenticatedWebSession;
import org.apache.wicket.authroles.authorization.strategies.role.Roles;
import org.apache.wicket.request.IRequestParameters;
import org.apache.wicket.request.Request;
import org.apache.wicket.request.cycle.RequestCycle;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.apache.wicket.util.string.StringValue;
import org.apache.wicket.util.string.Strings;

import ro.fortsoft.wicket.dashboard.Dashboard;
import ro.fortsoft.wicket.dashboard.Widget;
import ro.fortsoft.wicket.dashboard.WidgetFactory;
import ro.fortsoft.wicket.dashboard.web.DashboardContext;

public class WebSession extends AbstractAuthenticatedWebSession {
	private static final long serialVersionUID = 1L;
	public static int MILLIS_IN_MINUTE = 60000;
	public static final String SECURE_HASH = "secureHash";
	public static final String INVITATION_HASH = "invitationHash";
	private long userId = -1;
	private Set<Right> rights = new HashSet<User.Right>(); //TODO renew somehow on user edit !!!!
	private long languageId = -1; //TODO renew somehow on user edit !!!!
	private String SID = null;
	private OmUrlFragment area = null;
	private TimeZone tz;
	private TimeZone browserTz;
	public final static String ISO8601_FORMAT_STRING = "yyyy-MM-dd'T'HH:mm:ssZ";
	private DateFormat ISO8601FORMAT = new SimpleDateFormat(ISO8601_FORMAT_STRING); //FIXME not thread safe
	private DateFormat sdf;
	private UserDashboard dashboard;
	private Locale browserLocale = null;
	private Long recordingId;
	private Long loginError = null;
	private String externalType;
	public static boolean kickedByAdmin = false;
	public final static List<String> AVAILABLE_TIMEZONES = Arrays.asList(TimeZone.getAvailableIDs());
	public final static Set<String> AVAILABLE_TIMEZONE_SET = new LinkedHashSet<String>(AVAILABLE_TIMEZONES);
	
	public WebSession(Request request) {
		super(request);
		browserLocale = getLocale();
	}

	@Override
	public void invalidate() {
		removeOnlineUser(getClientByKeys(getUserId(), get().getId()));
		super.invalidate();
		userId = -1;
		rights = new HashSet<User.Right>();
		SID = null;
		sdf = null;
		recordingId = null;
		externalType = null;
		tz = null;
		browserTz = null;
		loginError = null;
		browserLocale = null;
	}
	
	@Override
	public Roles getRoles() {
		//first of all will check hashes
		try {
			IRequestParameters params = RequestCycle.get().getRequest().getRequestParameters();
			StringValue secureHash = params.getParameterValue(SECURE_HASH);
			StringValue invitationHash = params.getParameterValue(INVITATION_HASH);
			if (!secureHash.isEmpty() || !invitationHash.isEmpty()) {
				PageParameters pp = new PageParameters();
				for (String p : params.getParameterNames()) {
					List<StringValue> vals = params.getParameterValues(p);
					if (vals != null) {
						for (StringValue sv : vals) {
							if (!sv.isEmpty()) {
								pp.add(p, sv.toString());
							}
						}
					}
				}
				if (isSignedIn()) {
					invalidate();
				}
				throw new RestartResponseAtInterceptPageException(SwfPage.class, pp);
			}
		} catch (RestartResponseAtInterceptPageException e) {
			throw e;
		} catch (Exception e) {
			//no-op, will continue to sign-in page
		}
		if (rights.isEmpty()) {
			isSignedIn();
		}
		Roles r = new Roles();
		for (Right right : rights) {
			r.add(right.name());
		}
		return r;
	}

	@Override
	public boolean isSignedIn() {
		if (userId < 1) {
			IAuthenticationStrategy strategy = getAuthenticationStrategy();
			// get username and password from persistence store
			String[] data = strategy.load();
			if (data != null && data.length > 3 && data[2] != null) {
				Long domainId = null;
				try {
					domainId = Long.parseLong(data[3]);
				} catch (Exception e) {
					//no-op
				}
				// try to sign in the user
				if (!signIn(data[0], data[1], Type.valueOf(data[2]), domainId)) {
					// the loaded credentials are wrong. erase them.
					strategy.remove();
				}
			}
		}
		return userId > -1;
	}

	public boolean signIn(String secureHash) {
		//FIXME code is duplicated from MainService, need to be unified
		SOAPLoginDao soapDao = getBean(SOAPLoginDao.class);
		SOAPLogin soapLogin = soapDao.get(secureHash);
		if (soapLogin != null && !soapLogin.getUsed()) { //add code for  || (soapLogin.getAllowSameURLMultipleTimes())
			SessiondataDao sessionDao = getBean(SessiondataDao.class);
			Sessiondata sd = sessionDao.getSessionByHash(soapLogin.getSessionHash());
			if (sd != null && sd.getSessionXml() != null) {
				RemoteSessionObject remoteUser = RemoteSessionObject.fromXml(sd.getSessionXml());
				if (remoteUser != null && !Strings.isEmpty(remoteUser.getExternalUserId())) {
					UserDao userDao = getBean(UserDao.class);
					User user = userDao.getExternalUser(remoteUser.getExternalUserId(), remoteUser.getExternalUserType());
					if (user == null) {
						user = userDao.getNewUserInstance(null);
						user.setFirstname(remoteUser.getFirstname());
						user.setLastname(remoteUser.getLastname());
						user.setLogin(remoteUser.getUsername()); //FIXME check if login UNIQUE
						user.setExternalUserId(remoteUser.getExternalUserId());
						user.setExternalUserType(remoteUser.getExternalUserType());
						user.getRights().add(Right.Room);
						user.getAdresses().setEmail(remoteUser.getEmail());
						user.setPictureuri(remoteUser.getPictureUrl());
					} else {
						user.setFirstname(remoteUser.getFirstname());
						user.setLastname(remoteUser.getLastname());
						user.setPictureuri(remoteUser.getPictureUrl());
					}
					user = userDao.update(user, null);

					soapLogin.setUsed(true);
					soapLogin.setUseDate(new Date());
					//soapLogin.setClientURL(clientURL); //FIXME
					soapDao.update(soapLogin);

					sessionDao.updateUser(SID, user.getUser_id());
					setUser(user);
					recordingId = soapLogin.getRoomRecordingId();
					return true;
				}
			}
		}
		return false;
	}
	
	private void setUser(User u) {
		userId = u.getUser_id();
		rights = Collections.unmodifiableSet(u.getRights());
		languageId = u.getLanguage_id();
		externalType = u.getExternalUserType();
		tz = getBean(TimezoneUtil.class).getTimeZone(u);
		ISO8601FORMAT.setTimeZone(tz);
		setLocale(languageId == 3 ? Locale.GERMANY : LabelDao.languages.get(languageId)); //FIXME hack
		//FIXMW locale need to be set by User language first
		sdf = DateFormat.getDateTimeInstance(SHORT, SHORT, getLocale());
		if (null == getId()) {
			bind();
		}
	}
	
	public boolean signIn(String login, String password, Type type, Long domainId) {
		try {
			User u = null;
			switch (type) {
				case ldap:
					u = getBean(LdapLoginManagement.class).login(login, password, domainId);
					break;
				case user:
					/* we will allow login against internal DB in case user 'guess' LDAP password */
					u = getBean(UserDao.class).login(login, password);
					break;
				case oauth:
					// we did all the checks at this stage, just set the user
					u = getBean(UserDao.class).getByLogin(login, Type.oauth, domainId);
					break;
				default:
					throw new OmException(-1L);
			}
			if (u == null) {
				return false;
			}
			signIn(u);
			return true;
		} catch (OmException oe) {
			loginError = oe.getCode() == null ? -1L : oe.getCode();
		}
		return false;
	}
	
	public boolean signIn(User u) {
		Sessiondata sessData = getBean(SessiondataDao.class).startsession();
		SID = sessData.getSession_id();
		if (u == null) {
			return false;
		}
		setUser(u);
		return true;
	}
	
	public Long getLoginError() {
		return loginError;
	}
	
	public static WebSession get() {
		return (WebSession)AbstractAuthenticatedWebSession.get();
	}
	
	public void setLanguage(long languageId) {
		this.languageId = languageId;
	}
	
	public static long getLanguage() {
		checkIsInvalid();
		WebSession session = get();
		if (session.languageId < 0) {
			if (session.isSignedIn()) {
				session.languageId = getBean(UserDao.class).get(session.userId).getLanguage_id();
			} else {
				session.languageId = getBean(ConfigurationDao.class).getConfValue(CONFIG_DEFAULT_LANG_KEY, Long.class, "1");
			}
		}
		return session.languageId;
	}
	
	public String getValidatedSid() {
		SessiondataDao sessionDao = getBean(SessiondataDao.class);
		Long _userId = sessionDao.checkSession(SID);
		if (_userId == null || userId != _userId) {
			Sessiondata sessionData = sessionDao.getSessionByHash(SID);
			if (sessionData == null) {
				sessionData = sessionDao.startsession();
			}
			if (!sessionDao.updateUser(sessionData.getSession_id(), userId, false, languageId)) {
				//something bad, force user to re-login
				invalidate();
			} else {
				SID = sessionData.getSession_id();
			}
		}
		return SID;
	}
	
	public static String getSid() {
		return get().getValidatedSid();
	}

	public static long getUserId() {
		checkIsInvalid();
		return get().userId;
	}
	
	public static Long getRecordingId() {
		return get().recordingId;
	}
	
	public static String getExternalType() {
		return get().externalType;
	}
	
	public static TimeZone getUserTimeZone() {
		return get().tz;
	}

	public static Calendar getCalendar() {
		return Calendar.getInstance(get().tz);
	}

	public static Calendar getClientCalendar() {
		return Calendar.getInstance(getClientTimeZone());
	}

	public static DateFormat getIsoDateFormat() {
		return get().ISO8601FORMAT;
	}
	
	public static DateFormat getDateFormat() {
		return get().sdf;
	}
	
	public static Set<Right> getRights() {
		checkIsInvalid();
		return get().rights;
	}
	
	public static void setKickedByAdmin(boolean kicked) {
		kickedByAdmin = kicked;
	}
	
	public boolean isKickedByAdmin() {
		return kickedByAdmin;
	}

	public OmUrlFragment getArea() {
		return area;
	}

	public void setArea(OmUrlFragment area) {
		this.area = area;
	}

	
	public static Dashboard getDashboard() {
		Dashboard d = get().dashboard;
		if (d == null) {
			get().initDashboard();
			d = get().dashboard;
		}
		return d;
	}
	
	public Locale getBrowserLocale(){
		return browserLocale;
	}

	public Long getLanguageByBrowserLocale() {
		return getBean(IUserManager.class).getLanguage(getBrowserLocale());
	}

	public State getCountryByBrowserLocale() {
		return getBean(IUserManager.class).getCountry(getBrowserLocale());
	}

	public String getClientTZCode() {
		TimeZone _zone = browserTz;
		if (browserTz == null) {
			try {
				browserTz = getClientInfo().getProperties().getTimeZone();
				if (!AVAILABLE_TIMEZONE_SET.contains(browserTz.getID())) {
					for (String availableID : AVAILABLE_TIMEZONES) {
						TimeZone zone = TimeZone.getTimeZone(availableID);
						if (zone.hasSameRules(browserTz)) {
							browserTz = zone;
							break;
						}
					}
				}
				_zone = browserTz;
			} catch (Exception e) {
				_zone = Calendar.getInstance(getBrowserLocale()).getTimeZone();
			}
		}
		return _zone == null ? null : _zone.getID();
	}
	
	public static TimeZone getClientTimeZone() {
		String tzCode = get().getClientTZCode();
		return tzCode == null ? null : TimeZone.getTimeZone(tzCode);
	}
	
	private void initDashboard() {
		DashboardContext dashboardContext = getDashboardContext();
		dashboard = (UserDashboard)dashboardContext.getDashboardPersister().load();
		boolean existMyRoomWidget = false, existRssWidget = false;
		ConfigurationDao cfgDao = getBean(ConfigurationDao.class);
		boolean showMyRoomConfValue = 1 == cfgDao.getConfValue(CONFIG_DASHBOARD_SHOW_MYROOMS_KEY, Integer.class, "0");
		boolean showRssConfValue = 1 == cfgDao.getConfValue(CONFIG_DASHBOARD_SHOW_RSS_KEY, Integer.class, "0");
		boolean save = false;

		WidgetFactory widgetFactory = dashboardContext.getWidgetFactory();

		if (dashboard == null) {
			dashboard = new UserDashboard("default", "Default");

			dashboard.addWidget(widgetFactory.createWidget(new WelcomeWidgetDescriptor()));
			dashboard.addWidget(widgetFactory.createWidget(new StartWidgetDescriptor()));
			if (showMyRoomConfValue) {
				dashboard.addWidget(widgetFactory.createWidget(new MyRoomsWidgetDescriptor()));
			}
			if (showRssConfValue) {
				dashboard.addWidget(widgetFactory.createWidget(new RssWidgetDescriptor()));
			}
			save = true;
		} else {
			for (Iterator<Widget> iter = dashboard.getWidgets().iterator(); iter.hasNext();) {
				Widget w = iter.next();
				// PrivateRoomWidget is stored in the profile of user. Now, Show_MyRooms_key is disable.
				if (w.getClass().equals(MyRoomsWidget.class)) {
					existMyRoomWidget = true;
					if (!showMyRoomConfValue) {
						iter.remove();
					}
				} else if ((w.getClass().equals(RssWidget.class))) {
					// RssWidget is stored in the profile of user. Now, Show_RSS_Key is disable.
					existRssWidget = true;
					if (!showRssConfValue) {
						iter.remove();
					}
				} else {
					w.init();
				}
			}
			// PrivateRoomWidget was deleted from profile and now it's enabled. It's added again to dashboard.
			if (!existMyRoomWidget && showMyRoomConfValue && !dashboard.isWidgetMyRoomsDeleted()) {
				dashboard.addWidget(widgetFactory.createWidget(new MyRoomsWidgetDescriptor()));
				save = true;
			}
			// RssWidget was deleted from profile and now it's enabled. It's added again to dashboard.
			if (!existRssWidget && showRssConfValue && !dashboard.isWidgetRssDeleted()) {
				dashboard.addWidget(widgetFactory.createWidget(new RssWidgetDescriptor()));
				save = true;
			}
		}
		if (save) {
			dashboardContext.getDashboardPersister().save(dashboard);
		}
	}
	
	private static void checkIsInvalid() {
		if (isInvaldSession(get().getId())) {
			setKickedByAdmin(true);
			removeInvalidSession(get().getId());
			org.apache.wicket.Session session = (org.apache.wicket.Session)get();
			session.invalidate();
			Application.get().restartResponseAtSignInPage();
		}
	}
}
