package cz.muni.fi.pa165.soccermanager.security;

import cz.muni.fi.pa165.soccermanager.entity.User;
import cz.muni.fi.pa165.soccermanager.repository.PlayerRepository;
import cz.muni.fi.pa165.soccermanager.repository.TeamRepository;
import cz.muni.fi.pa165.soccermanager.repository.UserRepository;
import java.util.Optional;
import javax.persistence.EntityNotFoundException;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

@RequiredArgsConstructor
@Component("sc")
public class ScopesChecker {
  private final UserRepository userRepository;
  private final TeamRepository teamRepository;
  private final PlayerRepository playerRepository;

  public boolean thisUserOrAdmin(Long user) {
    return hasScope("SCOPE_ADMIN") || thisUser(user);
  }

  public boolean thisUser(Long user) {
    return getUserById(user)
        .getNickName()
        .equals(SecurityContextHolder.getContext().getAuthentication().getName());
  }

  public boolean teamOwnerOrAdmin(Long team) {
    final var user =  getUserByTeamId(team);
    return hasScope("SCOPE_ADMIN") || (user.isPresent() && user.get()
        .getNickName()
        .equals(SecurityContextHolder.getContext().getAuthentication().getName()));
  }

  public boolean playerOwnerOrAdmin(Long player) {
    final var p =  playerRepository.findById(player).orElseThrow(() -> {
      throw new EntityNotFoundException();
    });
    if (p.getTeam() == null) {
      return hasScope("SCOPE_ADMIN");
    }
    return teamOwnerOrAdmin(p.getTeam().getId());
  }

  private User getUserById(Long user){
    return userRepository.findById(user).orElseThrow(() -> {
      throw new EntityNotFoundException();
    });
  }

  private Optional<User> getUserByTeamId(Long team){
    return Optional.ofNullable(teamRepository.findById(team).orElseThrow(() -> {
      throw new EntityNotFoundException();
    }).getUser());
  }

  public boolean hasScope(String scope) {
    final var auth = SecurityContextHolder.getContext().getAuthentication();

    for (var s : auth.getAuthorities()) {
      if (s.getAuthority().equals(scope)) {
        return true;
      }
    }

    return false;
  }
}
