package app.service;

import app.model.Users;
import app.repository.UsersRepository;

import ca.tecreations.StringTool;
import ca.tecreations.db.mysql.MySQL;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
 
//@Configuration
@Service
// not necessary, yet: @Transactional
public class MyUserDetailsService implements UserDetailsService {

    @Autowired
    private DriverManagerDataSource dataSource;
    
    @Autowired
    private UsersRepository usersRepository;
    
    public MySQL mysql;

    public List<GrantedAuthority> getGrantedAuthorities(Users user) {
        if (user.getAuthorities() != null) return user.getAuthorities();
        List<String> roles = getAuthorities(user);
        List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
        for(int i = 0; i < roles.size();i++) {
            grantedAuthorities.add(new SimpleGrantedAuthority(roles.get(i)));
        }
        user.setAuthorities(grantedAuthorities);
        return grantedAuthorities;
    }
    
    public List<String> getAuthorities(Users user) {
        boolean debug = true;
        if (mysql == null) mysql = new MySQL(dataSource);
        String csv = mysql.getValues("SELECT authorities FROM users WHERE uid='" + user.getUID() + "'",debug).get(0);
        //System.out.println("CSV: " + csv);
        List<String> ints = StringTool.explode(csv,',');
        List<String> roles = new ArrayList<>();
        for(int i = 0; i < ints.size();i++) {
            String role = mysql.getValues("SELECT authority FROM authorities WHERE id='" + ints.get(i) + "'",debug).get(0);
            //System.out.println("Role: " + role);
            roles.add(role);
        } 
        return roles; 
    } 
    
    public String getUID(String email) { 
        boolean debug = true;
        if (mysql == null) mysql = new MySQL(dataSource);
        
        // attempt to retrieve by username
        String sql = "SELECT uid FROM users WHERE email='" + email + "'";
        return mysql.getValue(sql);
    }
    
    public String getHashedPass(Users user) {
        if (mysql == null) mysql = new MySQL(dataSource);
        String pass = mysql.getValue("SELECT password FROM users WHERE uid='" + user.getUID() + "'");
        return pass;
    } 
    
    @Override
    public Users loadUserByUsername(String email) throws UsernameNotFoundException {
        // search for user in database by username
        Optional<Users> data = usersRepository.findByEmail(email);
        if (!data.isPresent()) {
            System.err.println("MyUserDetailsService.loadUserByUsername: Could not find user: " + email);
            throw new UsernameNotFoundException("User not found.");
        }
        
        Users user = data.get();
        
        // get scopes/authorities
        List<GrantedAuthority> grantedAuthorities = getGrantedAuthorities(user);
        user.setAuthorities(grantedAuthorities);
        return user;
    }

    public void register(Users user) throws UsernameNotFoundException {
         usersRepository.save(user);
    }
}
  