package com.aemreunal.service;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import javax.validation.ConstraintViolationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.aemreunal.config.GlobalSettings;
import com.aemreunal.controller.DeleteResponse;
import com.aemreunal.domain.Project;
import com.aemreunal.domain.User;
import com.aemreunal.exception.project.ProjectNotFoundException;
import com.aemreunal.repository.project.ProjectRepo;
import com.aemreunal.repository.project.ProjectSpecs;

/*
 **************************
 * Copyright (c) 2014     *
 *                        *
 * This code belongs to:  *
 *                        *
 * Ahmet Emre Ünal        *
 * S001974                *
 *                        *
 * aemreunal@gmail.com    *
 * emre.unal@ozu.edu.tr   *
 *                        *
 * aemreunal.com          *
 **************************
 */

@Transactional
@Service
public class ProjectService {
    @Autowired
    private UserService userService;

    @Autowired
    private ProjectRepo projectRepo;

    @Autowired
    private BCryptPasswordEncoder encoder;

    /**
     * Saves/updates the given project. The given username parameter is used to set the
     * owner of the project when the project is first created (saved/persisted).
     *
     * @param username
     *     The username of the owner of the project
     * @param project
     *     The project to save/update
     *
     * @return The saved/updated project
     */
    public Project save(String username, Project project) throws ConstraintViolationException {
        if (GlobalSettings.DEBUGGING) {
            System.out.println("Saving project with ID = \'" + project.getProjectId() + "\'");
        }
        if (project.getOwner() == null) {
            project.setOwner(userService.findByUsername(username));
        }
        return projectRepo.save(project);
    }

    /**
     * Resets the project secret.
     * <p/>
     * Generates a new secret UUID, encodes it with BCrypt and stores it encoded but
     * returns the plaintext, so that it can be shown to the user.
     *
     * @return The plain-text project secret
     */
    public String resetSecret(String username, Project project) throws ProjectNotFoundException {
        String secret = UUID.randomUUID().toString().toUpperCase();
        project.setProjectSecret(encoder.encode(secret));
        this.save(username, project);
        return secret;
    }

    /**
     * Returns the list of all the projects. Will only work in debug mode. Otherwise, will
     * only return an empty list.
     *
     * @return A list of all projects
     */
    public List<Project> findAll() {
        if (GlobalSettings.DEBUGGING) {
            System.out.println("Finding all projects");
        }

        List<Project> projectList = new ArrayList<Project>();

// TODO        if (GlobalSettings.DEBUGGING) {
        for (Project project : projectRepo.findAll()) {
            projectList.add(project);
        }
//        }

        return projectList;
    }

    /**
     * Find the projects that belong to the specific {@link com.aemreunal.domain.User
     * User} with the specified username. Searches through the projects, matching the
     * {@link com.aemreunal.domain.User User} with the specified username.
     *
     * @param ownerUsername
     *     The username of the {@link com.aemreunal.domain.User User} to find the projects
     *     of
     *
     * @return The list of projects that belong to the {@link com.aemreunal.domain.User
     * User} with the specified username
     */
    public List<Project> findAllBelongingTo(String ownerUsername) {
        User owner = userService.findByUsername(ownerUsername);
        return this.findAllBelongingTo(owner);
    }

    /**
     * Find the projects that belong to a specific {@link com.aemreunal.domain.User User}.
     * Searches through the projects, matching the specified {@link
     * com.aemreunal.domain.User User}.
     *
     * @param owner
     *     The {@link com.aemreunal.domain.User User} to find the projects of
     *
     * @return The list of projects that belong to the {@link com.aemreunal.domain.User
     * User}
     */
    public List<Project> findAllBelongingTo(User owner) {
        // TODO or, find the user and .getProjects()?
        List<Project> projectList = new ArrayList<Project>();
        for (Project project : projectRepo.findByOwner(owner)) {
            projectList.add(project);
        }
        return projectList;
    }

    /**
     * Find projects conforming to specifications
     *
     * @param username
     *     The username of the owner of the projects to search for
     * @param projectName
     *     The project Name field constraint
     *
     * @return The list of projects conforming to given constraints
     */
    public List<Project> findProjectsBySpecs(String username, String projectName) {
        if (GlobalSettings.DEBUGGING) {
            System.out.println("Finding projects with Project Name = \'" + projectName + "\'");
        }

        List<Project> projectList = new ArrayList<Project>();
        User owner = userService.findByUsername(username);
        for (Object projectObject : projectRepo.findAll(ProjectSpecs.projectWithSpecification(owner, projectName))) {
            projectList.add((Project) projectObject);
        }

        return projectList;
    }

    /**
     * Finds the project with the given ID
     *
     * @param username
     *     The username of the owner of the project
     * @param id
     *     The ID of the project to search for
     *
     * @return The project the given ID
     *
     * @throws ProjectNotFoundException
     */
    public Project findById(String username, Long id) throws ProjectNotFoundException {
        if (GlobalSettings.DEBUGGING) {
            System.out.println("Finding project with ID = \'" + id + "\'");
        }
        User owner = userService.findByUsername(username);
        Project project = projectRepo.findByOwnerAndProjectId(owner, id);
        if (project == null) {
            throw new ProjectNotFoundException();
        }
        return project;
    }

    /**
     * Deletes the project with the given ID and deletes the beacons and beacon groups in
     * the project
     *
     * @param username
     *     The username of the owner of the project
     * @param projectId
     *     The ID of the project to delete
     *
     * @return Whether the project was deleted or not
     */
    public DeleteResponse delete(String username, Long projectId) {
        if (GlobalSettings.DEBUGGING) {
            System.out.println("Deleting project with ID = \'" + projectId + "\'");
        }
        Project project = this.findById(username, projectId);
        projectRepo.delete(project);
        return DeleteResponse.DELETED;
    }
}

@@ -2675,600 +2675,8 @@
  %7D%0A%0A
-    /**%0A     * Returns the list of all the projects. Will only work in debug mode. Otherwise, will%0A     * only return an empty list.%0A     *%0A     * @return A list of all projects%0A     */%0A    public List%3CProject%3E findAll() %7B%0A        if (GlobalSettings.DEBUGGING) %7B%0A            System.out.println(%22Finding all projects%22);%0A        %7D%0A%0A        List%3CProject%3E projectList = new ArrayList%3CProject%3E();%0A%0A// TODO        if (GlobalSettings.DEBUGGING) %7B%0A        for (Project project : projectRepo.findAll()) %7B%0A            projectList.add(project);%0A        %7D%0A//        %7D%0A%0A        return projectList;%0A    %7D%0A%0A
     
@@ -2757,32 +2757,32 @@
 nal.domain.User%0A
+
      * User%7D wit
@@ -3346,548 +3346,8 @@
 e);%0A
-        return this.findAllBelongingTo(owner);%0A    %7D%0A%0A    /**%0A     * Find the projects that belong to a specific %7B@link com.aemreunal.domain.User User%7D.%0A     * Searches through the projects, matching the specified %7B@link%0A     * com.aemreunal.domain.User User%7D.%0A     *%0A     * @param owner%0A     *     The %7B@link com.aemreunal.domain.User User%7D to find the projects of%0A     *%0A     * @return The list of projects that belong to the %7B@link com.aemreunal.domain.User%0A     * User%7D%0A     */%0A    public List%3CProject%3E findAllBelongingTo(User owner) %7B%0A
     
@@ -3493,37 +3493,26 @@
 t : 
-projectRepo.findByOwner(owner
+owner.getProjects(
 )) %7B

Remove redundant methods