package info.bukova.isspst.services;

import info.bukova.isspst.data.OwnedDataModel;
import info.bukova.isspst.data.User;
import org.hibernate.NonUniqueResultException;
import org.hibernate.Query;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

public class AbstractOwnedService<T extends OwnedDataModel> extends AbstractService<T> {
	
	@Override
	@Transactional
	@PreAuthorize("hasPermission(this, 'PERM_ADD')")
	public void add(T entity) {
		validate(entity);
		entity.setCreated(new Date());
		entity.setOwnedBy(getLoggedInUser());
		dao.add(entity);
	}
	
	@Override
	@Transactional
	@PreAuthorize("hasPermission(this, 'PERM_EDIT') or hasPermission(#entity, this.getUpdateEntityPermission())")
	public void update(T entity) {
		validate(entity);
		entity.setModifiedBy(getLoggedInUser());
		entity.setModified(new Date());
		dao.modify(entity);
		maintainStorrage();
	}
	
	@Transactional
	protected User getLoggedInUser() {
		if (!this.isFakeLogin() && sessionData.getCurrentUser() != null) {
			return sessionData.getCurrentUser();
		}
		
		try {
			String query = "from User where USERNAME = '" + ((UserDetails)SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername() + "'";
			Query q = dao.getQuery(query);
			return (User) q.uniqueResult();
		} catch (NonUniqueResultException e) {
			return null;
		}
	}
	
	private boolean isFakeLogin() {
		User user = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		if (user != null && user.getLastName() != null && user.getLastName().equals("fakeLogin")) {
			return true;
		}
		
		return false;
	}

}
