package org.academiadecodigo.bootcamp.fxlogin.service.bootcamp;

import org.academiadecodigo.bootcamp.fxlogin.model.Bootcamp;
import org.academiadecodigo.bootcamp.fxlogin.model.Cadet;
import org.academiadecodigo.bootcamp.fxlogin.persistence.TransactionException;
import org.academiadecodigo.bootcamp.fxlogin.persistence.dao.BootcampDao;
import org.academiadecodigo.bootcamp.fxlogin.persistence.dao.CadetDao;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * MIT License
 * (c) 2017 Ricardo Constantino
 */

public class BootcampServiceImpl implements BootcampService {
    private BootcampDao bootcampDao;
    private CadetDao cadetDao;

    private Integer selectedBootcamp;

    public BootcampServiceImpl(BootcampDao bootcampDao, CadetDao cadetDao) {
        this.bootcampDao = bootcampDao;
        this.cadetDao = cadetDao;
    }

    @Transactional(rollbackFor = TransactionException.class)
    @Override
    public void createBootcamp(Integer id, Bootcamp.Location location, String start, String end) throws TransactionException {
        bootcampDao.saveOrUpdate(new Bootcamp(id, location, start, end));
    }

    @Transactional(rollbackFor = TransactionException.class)
    @Override
    public void addBootcamp(Bootcamp bootcamp) throws TransactionException {
        if (bootcampDao.findById(bootcamp.getId()) == null) {
            bootcampDao.saveOrUpdate(bootcamp);
        }
    }

    @Transactional(rollbackFor = TransactionException.class)
    @Override
    public void addCodeCadet(Integer bootcampId, Cadet cadet) throws TransactionException {
        Bootcamp bootcamp = bootcampDao.findById(bootcampId);

        if (bootcamp != null) {
            bootcamp.addCodeCadet(cadet);
            bootcampDao.saveOrUpdate(bootcamp);
        }
    }

    @Transactional(rollbackFor = TransactionException.class)
    @Override
    public void addCodeCadets(Integer bootcampId, Cadet... cadets) throws TransactionException {

        Bootcamp bootcamp = bootcampDao.findById(bootcampId);

        if (bootcamp != null) {
            for (Cadet cadet : cadets) {
                bootcamp.addCodeCadet(cadet);
            }
            bootcampDao.saveOrUpdate(bootcamp);
        }
    }

    @Transactional(readOnly = true)
    @Override
    public Bootcamp getById(Integer bootcampId) {
        return bootcampDao.findById(bootcampId);
    }

    @Transactional(readOnly = true)
    @Override
    public List<Bootcamp> listBootcamps() {
        return bootcampDao.findAll();
    }

    @Transactional(readOnly = true)
    @Override
    public Set<Cadet> listCodeCadets(Integer bootcampId) {
        Set<Cadet> cadets = new HashSet<>();
        Bootcamp bootcamp = bootcampDao.findById(bootcampId);
        if (bootcamp != null) {
            cadets = bootcamp.getCadets();
        }
        return cadets;
    }

    @Override
    public void setSelectedBootcamp(Integer bootcampId) {
        selectedBootcamp = bootcampId;
    }

    @Override
    public Integer getSelectedBootcamp() {
        return selectedBootcamp;
    }
}
