/*
 * 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.axis.services;

import org.apache.axis2.AxisFault;
import org.apache.openmeetings.db.dto.basic.ErrorResult;
import org.apache.openmeetings.db.dto.user.UserSearchResult;
import org.apache.openmeetings.db.entity.server.Sessiondata;

public class UserWebServiceFacade extends BaseWebService {

	/**
	 * load this session id before doing anything else
	 * 
	 * @return Sessiondata-Object
	 */
	public Sessiondata getSession() throws AxisFault {
		return getBean(UserWebService.class).getSession();
	}

	/**
	 * auth function, use the SID you get by getSession
	 * 
	 * @param SID
	 * @param Username
	 * @param Userpass
	 * @return positive means Loggedin, if negativ its an ErrorCode, you have to
	 *         invoke the Method getErrorByCode to get the Text-Description of
	 *         that ErrorCode
	 */
	public Long loginUser(String SID, String username, String userpass)
			throws AxisFault {
		return getBean(UserWebService.class).loginUser(SID, username, userpass);
	}

	/**
	 * Gets the Error-Object
	 * 
	 * @param SID
	 * @param errorid
	 * @param language_id
	 * @return
	 * @throws AxisFault 
	 */
	public ErrorResult getErrorByCode(String SID, Long errorid, Long language_id) throws AxisFault {
		return getBean(UserWebService.class).getErrorByCode(SID, errorid, language_id);
	}

	public Long addNewUser(String SID, String username, String userpass,
			String lastname, String firstname, String email,
			String additionalname, String street, String zip, String fax,
			long states_id, String town, long language_id)
			throws AxisFault {
		return getBean(UserWebService.class).addNewUser(SID, username, userpass,
				lastname, firstname, email, additionalname, street, zip, fax,
				states_id, town, language_id);
	}

	public Long addNewUserWithTimeZone(String SID, String username,
			String userpass, String lastname, String firstname, String email,
			String additionalname, String street, String zip, String fax,
			long states_id, String town, long language_id,
			String jNameTimeZone) throws AxisFault {
		return getBean(UserWebService.class).addNewUserWithTimeZone(SID, username,
				userpass, lastname, firstname, email, additionalname, street,
				zip, fax, states_id, town, language_id, jNameTimeZone);

	}

	/**
	 * 
	 * Adds a user with an externalUserId and type, but checks if the user/type
	 * does already exist
	 * 
	 * @param SID
	 * @param username
	 * @param userpass
	 * @param lastname
	 * @param firstname
	 * @param email
	 * @param additionalname
	 * @param street
	 * @param zip
	 * @param fax
	 * @param states_id
	 * @param town
	 * @param language_id
	 * @param jNameTimeZone
	 * @param externalUserId
	 * @param externalUserType
	 * @return
	 * @throws AxisFault
	 */
	public Long addNewUserWithExternalType(String SID, String username,
			String userpass, String lastname, String firstname, String email,
			String additionalname, String street, String zip, String fax,
			long states_id, String town, long language_id,
			String jNameTimeZone, String externalUserId, String externalUserType)
			throws AxisFault {
		return getBean(UserWebService.class).addNewUserWithExternalType(SID, username,
				userpass, lastname, firstname, email, additionalname, street,
				zip, fax, states_id, town, language_id, jNameTimeZone,
				externalUserId, externalUserType);

	}

	/**
	 * 
	 * delete a user by its id
	 * 
	 * @param SID
	 * @param userId
	 * @return
	 * @throws AxisFault
	 */
	public Long deleteUserById(String SID, Long userId) throws AxisFault {
		return getBean(UserWebService.class).deleteUserById(SID, userId);
	}

	/**
	 * 
	 * delete a user by its external user id and type
	 * 
	 * @param SID
	 * @param externalUserId
	 * @param externalUserType
	 * @return
	 * @throws AxisFault
	 */
	public Long deleteUserByExternalUserIdAndType(String SID,
			String externalUserId, String externalUserType) throws AxisFault {
		return getBean(UserWebService.class).deleteUserByExternalUserIdAndType(SID,
				externalUserId, externalUserType);
	}

	public String setUserObjectAndGenerateRoomHash(String SID, String username,
			String firstname, String lastname, String profilePictureUrl,
			String email, String externalUserId, String externalUserType,
			Long room_id, int becomeModeratorAsInt, int showAudioVideoTestAsInt)
			throws AxisFault {
		return getBean(UserWebService.class).setUserObjectAndGenerateRoomHash(SID,
				username, firstname, lastname, profilePictureUrl, email,
				externalUserId, externalUserType, room_id,
				becomeModeratorAsInt, showAudioVideoTestAsInt);
	}

	public String setUserObjectAndGenerateRoomHashByURL(String SID,
			String username, String firstname, String lastname,
			String profilePictureUrl, String email, String externalUserId,
			String externalUserType, Long room_id, int becomeModeratorAsInt,
			int showAudioVideoTestAsInt) throws AxisFault {
		return getBean(UserWebService.class).setUserObjectAndGenerateRoomHashByURL(SID,
				username, firstname, lastname, profilePictureUrl, email,
				externalUserId, externalUserType, room_id,
				becomeModeratorAsInt, showAudioVideoTestAsInt);
	}

	public String setUserObjectAndGenerateRoomHashByURLAndRecFlag(String SID,
			String username, String firstname, String lastname,
			String profilePictureUrl, String email, String externalUserId,
			String externalUserType, Long room_id, int becomeModeratorAsInt,
			int showAudioVideoTestAsInt, int allowRecording) throws AxisFault {
		return getBean(UserWebService.class)
				.setUserObjectAndGenerateRoomHashByURLAndRecFlag(SID, username,
						firstname, lastname, profilePictureUrl, email,
						externalUserId, externalUserType, room_id,
						becomeModeratorAsInt, showAudioVideoTestAsInt,
						allowRecording);
	}

	public String setUserObjectMainLandingZone(String SID, String username,
			String firstname, String lastname, String profilePictureUrl,
			String email, String externalUserId, String externalUserType)
			throws AxisFault {
		return getBean(UserWebService.class).setUserObjectMainLandingZone(SID,
				username, firstname, lastname, profilePictureUrl, email,
				externalUserId, externalUserType);
	}

	public String setUserAndNickName(String SID, String username,
			String firstname, String lastname, String profilePictureUrl,
			String email, String externalUserId, String externalUserType,
			Long room_id, int becomeModeratorAsInt,
			int showAudioVideoTestAsInt, int showNickNameDialogAsInt)
			throws AxisFault {
		return getBean(UserWebService.class).setUserAndNickName(SID, username,
				firstname, lastname, profilePictureUrl, email, externalUserId,
				externalUserType, room_id, becomeModeratorAsInt,
				showAudioVideoTestAsInt, showNickNameDialogAsInt);
	}

	public String setUserObjectAndGenerateRecordingHashByURL(String SID,
			String username, String firstname, String lastname,
			String externalUserId, String externalUserType, Long recording_id)
			throws AxisFault {
		return getBean(UserWebService.class)
				.setUserObjectAndGenerateRecordingHashByURL(SID, username,
						firstname, lastname, externalUserId, externalUserType,
						recording_id);
	}

	public Long addUserToOrganisation(String SID, Long user_id,
			Long organisation_id, Long insertedby)
			throws AxisFault {
		return getBean(UserWebService.class).addUserToOrganisation(SID, user_id,
				organisation_id, insertedby);
	}

	public UserSearchResult getUsersByOrganisation(String SID, long organisation_id, int start, int max, String orderby,
			boolean asc) throws AxisFault {
		return getBean(UserWebService.class).getUsersByOrganisation(SID, organisation_id, start, max, orderby, asc);
	}

	public Boolean kickUserByPublicSID(String SID, String publicSID)
			throws AxisFault {
		return getBean(UserWebService.class).kickUserByPublicSID(SID, publicSID);
	}
	
	public Long addOrganisation(String SID, String name) throws AxisFault {
		return getBean(UserWebService.class).addOrganisation(SID, name);
	}

}
