package com.tootsville.joshua.client.service;

import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
import com.tootsville.gwt.joshua.client.except.ForbiddenException;
import com.tootsville.gwt.joshua.client.except.InvalidCredentialsException;
import com.tootsville.gwt.joshua.client.except.NotFoundException;
import com.tootsville.gwt.joshua.client.except.PermissionRequiredException;

/**
 * 
 * TODO: Document this type. Dec 7, 2009 : theys
 * 
 * @author <a href="mailto:theys@resinteractive.com">Tim Heys</a>
 * 
 */
@RemoteServiceRelativePath ("service")
public interface JoshuaService extends RemoteService {

    /**
     * Fake a parent approval for a user account. This will allow the user to
     * chat.
     * 
     * @param userID
     */
    void approve (int userID);

    /**
     * 
     * TODO: Document this method. Dec 7, 2009 : theys
     * 
     * @param mail
     * @param newUserName
     * @throws NotFoundException
     * @throws InvalidCredentialsException
     */
    void associateChild (String mail, String newUserName)
            throws NotFoundException, InvalidCredentialsException;

    /**
     * 
     * Ban or unban a user.
     * 
     * @param userID Used to look up the User.
     */
    void banOrUnban (final int userID, final int lifeguardID,
            final String reason);

    /**
     * 
     * Cancel or uncancel a user.
     * 
     * @param userID Used to look up the User.
     */
    void cancelUser (final int userID);

    /**
     * Send a Parent object (client side) which will be translated into the
     * server Parent and used to create a new Parent account. This method can be
     * written to.
     * 
     * @param parent
     */
    void createNewParent (
            com.tootsville.gwt.joshua.client.util.Parent parent);

    /**
     * This method has been deprecated. Set a Staff level in a User object and
     * then use the
     * {@link JoshuaService#createOrEditUser(com.tootsville.gwt.joshua.client.util.User, boolean)}
     * method instead.
     * 
     * @param person
     */
    @Deprecated
    void createNewStaff (
            com.tootsville.gwt.joshua.client.util.User person);

    /**
     * Create a new User account on server side from a loaded client User
     * object. The boolean createOrEdit specifies whether the account should
     * exist already on server side or not.
     * 
     * @param user
     * @param createOrEdit
     */
    void createOrEditUser (
            com.tootsville.gwt.joshua.client.util.User user,
            boolean createOrEdit);

    byte [] getKey ();

    /**
     * Pass a string of a User ID, Parent ID, User Login, Parent eMail, User
     * Cookie, Parent Cookie, or Invoice number in the format SOURCE-CODE. The
     * parameters will search the database for all that criteria in that order
     * and return the first reference it finds.
     * 
     * @param searchParam
     * @return
     * @throws NotFoundException
     */
    com.tootsville.gwt.joshua.client.util.Person getPerson (
            final String searchParam) throws NotFoundException;

    /**
     * 
     * TODO: document this method (theys, Oct 16, 2009)
     * 
     * @return
     */
    String getVersion ();

    /**
     * Add a staff compensated enrolment to a User. User is found by the userID
     * param, and the amount of time is specified by the months param. In this
     * package it is routine to have a user enter an integer of months or the
     * key word 'life' to prompt for number of months, and give an error if the
     * User actually inputs 0. This is done to avoid confusion.
     * 
     * @param userID
     * @param months
     */
    void giftTime (int userID, int months);

    /**
     * Create a server event of 'givenuts'. numNuts param specifies number of
     * peanuts to gift, and userID is used to find the User object. an
     * InvalidCredenitalsException can be thrown if numNuts cannot be converted
     * to a BigDecimal or a User cannot be found with the supplied userID
     * 
     * @param numNuts
     * @param userID
     * @return
     * @throws InvalidCredentialsException
     */
    String givePeanuts (long numNuts, int userID)
            throws InvalidCredentialsException;

    /**
     * 
     * Returns a User object after the username and password have been checked.
     * PermissionRequiredException is thrown if the User object does not have a
     * valid staff level of 1 or higher. InvalidCredentialsException is thrown
     * if no User is found with the username, or if the password does not match.
     * InvalidCredenitalsException will have an attached Message with an error
     * message, so you can call caught.getMessage() to display a user friendly
     * error message.
     * 
     * @param username
     * @param password
     * @return
     * @throws PermissionRequiredException
     * @throws InvalidCredentialsException
     */
    com.tootsville.gwt.joshua.client.util.User loginStaff (
            String username, String password)
            throws PermissionRequiredException,
            InvalidCredentialsException;

    /**
     * Send an e-mail to a User's responsible mail that tells them their
     * username and password. The boolean specifies to search for a user by ID
     * or a parent by ID.
     * 
     * @param userID
     * @param isUser true will search for a User with the supplied userID param,
     *        false will search for a Parent with the supplied userID
     */
    void remindPassword (int userID, boolean isUser);

    /**
     * Randomly generate a password for the user then send an e-mail to a User's
     * responsible mail that tells them their username and password. The boolean
     * specifies to search for a user by ID or a parent by ID.
     * 
     * @param userID
     * @param isUser true will search for a User with the supplied userID param,
     *        false will search for a Parent with the supplied userID
     */
    void resetPassword (int userID, boolean isUser);

    void setMail (int userID, String newMail)
            throws InvalidCredentialsException;

    /**
     * Set a new parent account for a user.
     * 
     * @param userID
     * @param newMail
     */
    void setParent (int userID, String newMail)
            throws InvalidCredentialsException;

    /**
     * eMail param will be verified as a real e-mail address. If the mail is
     * invalid an InvalidCredentialsException will be thrown.
     * 
     * @param eMail
     * @throws InvalidCredentialsException
     */
    void verifyMail (String eMail) throws InvalidCredentialsException;

    /**
     * userName param will be verified if it is able to be used as a username in
     * Tootsville. If the username is already taken or too short/long, an
     * {@link InvalidCredentialsException} will be thrown. If the username does
     * not pass the filters a {@link ForbiddenException} will be thrown.
     * 
     * @param userName
     * @throws InvalidCredentialsException
     * @throws ForbiddenException
     */
    void verifyUserName (String userName)
            throws InvalidCredentialsException, ForbiddenException;
}
