package hirondelle.predict.main.lists;

import static hirondelle.predict.main.lists.PredictionListAction.PREDICTION_LIST_ADD;
import static hirondelle.predict.main.lists.PredictionListAction.PREDICTION_LIST_CHANGE;
import static hirondelle.predict.main.lists.PredictionListAction.PREDICTION_LIST_DELETE;
import static hirondelle.predict.main.lists.PredictionListAction.PREDICTION_LIST_FETCH;
import static hirondelle.predict.main.lists.PredictionListAction.PREDICTION_LIST_FETCH_PUBLIC;
import static hirondelle.predict.main.lists.PredictionListAction.PREDICTION_LIST_LIST;
import hirondelle.web4j.database.DAOException;
import hirondelle.web4j.database.Db;
import hirondelle.web4j.database.ForeignKeyException;
import hirondelle.web4j.model.DateTime;
import hirondelle.web4j.model.Id;
import hirondelle.web4j.util.Util;

import java.util.List;

/** 
 Data Access Object (DAO) for {@link PredictionList} objects. 
 
 <P>All operations are related to a given user id.
*/
public final class PredictionListDAO {
  
  /** Return a <tt>List</tt> of all {@link PredictionList} objects for a given user.  */
  public List<PredictionList> list(Id aUserId) throws DAOException {
    return Db.list(PredictionList.class, PREDICTION_LIST_LIST, aUserId);
  }
  
  /** Return a single {@link PredictionList} identified by its id, and its user.  */
  public PredictionList fetch(Id aPredictionListId, Id aUserId) throws DAOException {
    return Db.fetch(PredictionList.class, PREDICTION_LIST_FETCH, aPredictionListId, aUserId);
  }
  
  /** Return a single public {@link PredictionList} identified by its id.  */
  public PredictionList fetchPublic(Id aPredictionListId) throws DAOException {
    return Db.fetch(PredictionList.class, PREDICTION_LIST_FETCH_PUBLIC, aPredictionListId);
  }
  
  /**
   Add a new {@link PredictionList} to the database.

   @param aToday defines the creation date of the list.
   @return the autogenerated database id, if any.
  */
  Id add(PredictionList aPredictionList, DateTime aToday) throws DAOException {
    Object[] params = {aPredictionList.getTitle(), aToday, aPredictionList.getUser()};
    return Db.add(PREDICTION_LIST_ADD, params);
  }
  
  /** Update an existing {@link PredictionList}.  The creation date cannot change. */
  boolean change(PredictionList aPredictionList) throws DAOException {
    Object[] params = {aPredictionList.getTitle(), aPredictionList.getId(), aPredictionList.getUser() };
    return Util.isSuccess(Db.edit(PREDICTION_LIST_CHANGE, params));
  }
  
  /**
   Delete a {@link PredictionList}.
   
   <P>If an item is linked to this {@link PredictionList}, then deletion will fail, and a 
   {@link ForeignKeyException} will be thrown.
  */
  void delete(Id aPredictionListId, Id aUserId) throws DAOException, ForeignKeyException {
    Db.edit(PREDICTION_LIST_DELETE, aPredictionListId, aUserId);
  }
  
}