/*
   * Commitment cannot be updated. This method always throws an exception.
   *
   * @see edu.wpi.cs.wpisuitetng.modules.EntityManager#update(edu.wpi.cs.wpisuitetng.Session, java.lang.String)
   */
  @Override
  public Commitment update(Session s, String content) throws WPISuiteException {
    Commitment updatedCommitment = Commitment.fromJSON(content);
    /*
     * Because of the disconnected objects problem in db4o, we can't just save Commitments.
     * We have to get the original defect from db4o, copy properties from updatedCommitment,
     * then save the original Commitment again.
     */
    List<Model> oldCommitments =
        db.retrieve(Commitment.class, "id", updatedCommitment.getID(), s.getProject());
    // System.out.println(oldCommitments.toString());
    if (oldCommitments.size() < 1 || oldCommitments.get(0) == null) {
      throw new BadRequestException("Commitment with ID does not exist.");
    }

    Commitment existingCommitment = (Commitment) oldCommitments.get(0);

    // copy values to old commitment and fill in our changeset appropriately
    existingCommitment.copyFrom(updatedCommitment);

    if (!db.save(existingCommitment, s.getProject())) {
      throw new WPISuiteException();
    }

    return existingCommitment;
  }
  @Override
  public void save(Session s, Project model) throws WPISuiteException {
    if (s == null) {
      throw new WPISuiteException("Null Session.");
    }
    // permissions checking happens in update, create, and delete methods only
    /*User theUser = s.getUser();
    if(Role.ADMIN.equals(theUser.getRole()) ||
    		Permission.WRITE.equals(model.getPermission(theUser))){*/
    if (data.save(model)) {
      logger.log(Level.FINE, "Project Saved :" + model);
      return;
    }
    /*else
    {
    	logger.log(Level.WARNING, "Project Save Failure!");
    	throw new DatabaseException("Save failure for Project."); // Session User: "******" Project: " + model.getName());
    }
    /*}
    else
    {
    	logger.log(Level.WARNING, "ProjectManager Save attempted by user with insufficient permission");
    	throw new UnauthorizedException("You do not have the requred permissions to perform this action.");
    }*/

  }
  /*
   * Saves a Commitment when it is received from a client
   *
   * @see edu.wpi.cs.wpisuitetng.modules.EntityManager#makeEntity(edu.wpi.cs.wpisuitetng.Session, java.lang.String)
   */
  @Override
  public Commitment makeEntity(Session s, String content)
      throws BadRequestException, ConflictException, WPISuiteException {

    // Parse the message from JSON
    final Commitment newMessage = Commitment.fromJSON(content);

    // System.out.println("EM: marked for delete:" + newMessage.isMarkedForDeletion());

    newMessage.setOwnerName(s.getUsername());
    newMessage.setOwnerID(s.getUser().getIdNum());

    // Until we find a id that is unique assume another commitment might already have it
    boolean unique;
    long id = 0;
    do {
      unique = true;
      id = UUID.randomUUID().getMostSignificantBits();
      for (Commitment c : this.getAll(s)) if (c.getUniqueID() == id) unique = false;
    } while (!unique);

    newMessage.setUniqueID(id);
    System.out.printf(
        "Server: Creating new commitment with id = %s and owner = %s\n",
        newMessage.getUniqueID(), newMessage.getOwnerName());

    // Save the message in the database if possible, otherwise throw an exception
    // We want the message to be associated with the project the user logged in to
    if (!db.save(newMessage, s.getProject())) {
      throw new WPISuiteException();
    }

    // Return the newly created message (this gets passed back to the client)
    return newMessage;
  }
 public Project[] getEntityByName(Session s, String projectName)
     throws NotFoundException, WPISuiteException {
   Project[] m = new Project[1];
   if (projectName.equalsIgnoreCase("")) {
     throw new NotFoundException("No (blank) Project name given.");
   } else {
     return data.retrieve(project, "name", projectName).toArray(m);
   }
 }
 @Override
 public Project[] getEntity(Session s, String id) throws WPISuiteException {
   Project[] m = new Project[1];
   if (id.equalsIgnoreCase("")) {
     return getAll(s);
   } else {
     return data.retrieve(project, "idNum", id).toArray(m);
   }
 }
  @Override
  public boolean deleteEntity(Session s1, String id) throws WPISuiteException {
    if (s1 == null) {
      throw new WPISuiteException("Null Session.");
    }
    User theUser = s1.getUser();
    Project[] model = this.getEntity(id);
    if (model[0].getPermission(theUser).equals(Permission.WRITE)
        || theUser.getRole().equals(Role.ADMIN)) {
      Model m = data.delete(data.retrieve(project, "idNum", id).get(0));
      logger.log(Level.INFO, "ProjectManager deleting project <" + id + ">");

      return (m != null) ? true : false;
    } else {
      logger.log(
          Level.WARNING, "ProjectManager Delete attempted by user with insufficient permission");
      throw new UnauthorizedException(
          "You do not have the required permissions to perform this action.");
    }
  }
  /*
   * Returns all of the messages that have been stored.
   *
   * @see edu.wpi.cs.wpisuitetng.modules.EntityManager#getAll(edu.wpi.cs.wpisuitetng.Session)
   */
  @Override
  public Commitment[] getAll(Session s) throws WPISuiteException {
    // Ask the database to retrieve all objects of the type Commitment.
    // Passing a dummy Commitment lets the db know what type of object to retrieve
    // Passing the project makes it only get messages from that project
    System.out.println("Server: Retrieving all commitments");

    List<Model> messages = db.retrieveAll(new Commitment(), s.getProject());

    // Return the list of messages as an array
    return messages.toArray(new Commitment[0]);
  }
 @Override
 public void deleteAll(Session s) throws WPISuiteException {
   User theUser = s.getUser();
   logger.log(Level.INFO, "ProjectManager invoking DeleteAll...");
   if (theUser.getRole().equals(Role.ADMIN)) {
     data.deleteAll(new Project("", ""));
   } else {
     logger.log(
         Level.WARNING, "ProjectManager DeleteAll attempted by user with insufficient permission");
     throw new UnauthorizedException(
         "You do not have the required permissions to perform this action.");
   }
 }
 /*
  * Messages cannot be deleted
  *
  * @see edu.wpi.cs.wpisuitetng.modules.EntityManager#deleteEntity(edu.wpi.cs.wpisuitetng.Session, java.lang.String)
  */
 @Override
 public boolean deleteEntity(Session s, String id) throws WPISuiteException {
   System.out.printf("Server: Deleting commitment with id = %s\n", id);
   try {
     Commitment todelete =
         (Commitment)
             db.retrieve(Commitment.class, "UniqueID", Long.parseLong(id), s.getProject()).get(0);
     deleteCommitment(todelete);
     return true;
   } catch (Exception e) {
     e.printStackTrace();
     return false;
   }
 }
  /**
   * returns a project without requiring a session, specifically for the scenario where a session
   * needs to be created. only ever returns one project, "" is not a valid argument;
   *
   * @param id - the id of the user, in this case it's the idNum
   * @return a list of matching projects
   * @throws NotFoundException if the project cannot be found
   * @throws WPISuiteException if retrieve fails
   */
  public Project[] getEntity(String id) throws NotFoundException, WPISuiteException {
    Project[] m = new Project[1];
    if (id.equalsIgnoreCase("")) {
      throw new NotFoundException("No (blank) Project id given.");
    } else {
      m = data.retrieve(project, "idNum", id).toArray(m);

      if (m[0] == null) {
        throw new NotFoundException("Project with id <" + id + "> not found.");
      } else {
        return m;
      }
    }
  }
  @Override
  public Project update(Session s, String content) throws WPISuiteException {
    Project[] p = null;

    String id = AbstractEntityManager.parseFieldFromJSON(content, "idNum");

    if (id.equalsIgnoreCase("")) {
      throw new NotFoundException("No (blank) Project id given.");
    } else {
      p = data.retrieve(project, "idNum", id).toArray(p);

      if (p[0] == null) {
        throw new NotFoundException("Project with id <" + id + "> not found.");
      }
    }

    return update(s, p[0], content);
  }
 /*
  * Individual commitments can be retrieved.
  *
  * @see edu.wpi.cs.wpisuitetng.modules.EntityManager#getEntity(edu.wpi.cs.wpisuitetng.Session, java.lang.String)
  */
 @Override
 public Commitment[] getEntity(Session s, String id) throws NotFoundException, WPISuiteException {
   System.out.printf("Server: Retrieving category with id = %s\n", id);
   return (Commitment[]) (db.retrieve(this.getClass(), "UniqueID", id, s.getProject()).toArray());
 }
 @Override
 public Project[] getAll(Session s) {
   Project[] ret = new Project[1];
   ret = data.retrieveAll(new Project("", "")).toArray(ret);
   return ret;
 }
 /*
  * @see edu.wpi.cs.wpisuitetng.modules.EntityManager#Count()
  */
 @Override
 public int Count() throws WPISuiteException {
   // Return the number of Commitments currently in the database
   return db.retrieveAll(new Commitment()).size();
 }
 /*
  * Commitments can be deleted
  *
  * @see edu.wpi.cs.wpisuitetng.modules.EntityManager#deleteAll(edu.wpi.cs.wpisuitetng.Session)
  */
 @Override
 public void deleteAll(Session s) throws WPISuiteException {
   db.deleteAll(new Commitment());
 }
 public void deleteCommitment(Commitment model) {
   db.delete(model);
 }
 /*
  * @see edu.wpi.cs.wpisuitetng.modules.EntityManager#save(edu.wpi.cs.wpisuitetng.Session, edu.wpi.cs.wpisuitetng.modules.Model)
  */
 @Override
 public void save(Session s, Commitment model) throws WPISuiteException {
   db.save(model, s.getProject());
 }