// Path: src/main/java/com/lyubenblagoev/postfixrest/entity/Role.java
// @Entity
// @Table(name = "roles")
// public class Role extends BaseEntity {
// 
//     public static final String ROLE_ADMIN = "ADMIN";
// 
//     @Column
//     private String name;
// 
//     @ManyToMany(mappedBy = "roles")
//     private List<User> users;
// 
//     public String getName() {
//         return name;
//     }
// 
//     public void setName(String name) {
//         this.name = name;
//     }
// 
//     public List<User> getUsers() {
//         return users;
//     }
// 
//     public void setUsers(List<User> users) {
//         this.users = users;
//     }
// }
// 
// Path: src/main/java/com/lyubenblagoev/postfixrest/entity/User.java
// @Entity
// @Table(name = "users")
// public class User extends BaseEntity {
// 
//     @Column(nullable = false)
//     private String email;
// 
//     @Column(nullable = false)
//     private String password;
// 
//     @OneToMany(orphanRemoval = true, cascade = CascadeType.ALL, mappedBy = "user")
//     private List<Device> devices = Collections.emptyList();
// 
//     @ManyToMany
//     @JoinTable(
//             name = "users_roles",
//             joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"),
//             inverseJoinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id")
//     )
//     private List<Role> roles;
// 
//     public User(String email, String password) {
//         super();
//         this.email = email;
//         this.password = password;
//         this.setEnabled(true);
//     }
// 
//     protected User() {
//     }
// 
//     public String getEmail() {
//         return email;
//     }
// 
//     public void setEmail(String email) {
//         this.email = email;
//     }
// 
//     public String getPassword() {
//         return password;
//     }
// 
//     public void setPassword(String password) {
//         this.password = password;
//     }
// 
//     public List<Device> getDevices() {
//         return devices;
//     }
// 
//     public void setDevices(List<Device> devices) {
//         this.devices = devices;
//     }
// 
//     public void addDevice(Device device) {
//         Objects.requireNonNull(device);
//         getDevices().add(device);
//         device.setUser(this);
//     }
// 
//     public void removeDevice(Device device) {
//         Objects.requireNonNull(device);
//         getDevices().remove(device);
//         device.setUser(null);
//     }
// 
//     public List<Role> getRoles() {
//         return roles;
//     }
// 
//     public void setRoles(List<Role> roles) {
//         this.roles = roles;
//     }
// }
// 
// Path: src/main/java/com/lyubenblagoev/postfixrest/repository/RoleRepository.java
// @Repository
// public interface RoleRepository extends JpaRepository<Role, Long> {
// 
//     List<Role> findByName(String name);
// 
// }
// 
// Path: src/main/java/com/lyubenblagoev/postfixrest/repository/UserRepository.java
// public interface UserRepository extends JpaRepository<User, Long> {
// 
//     @Query("FROM User u LEFT JOIN FETCH u.roles WHERE u.email = :email")
//     Optional<User> findByEmail(String email);
// 
// }


import com.lyubenblagoev.postfixrest.entity.Role;
import com.lyubenblagoev.postfixrest.entity.User;
import com.lyubenblagoev.postfixrest.repository.RoleRepository;
import com.lyubenblagoev.postfixrest.repository.UserRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;

    @Value("${users.default-user.password}")
    private String defaultUserPassword;

    public DefaultAdminUserInitializer(PasswordEncoder passwordEncoder,
                                       UserRepository userRepository,
                                       RoleRepository roleRepository) {
        this.passwordEncoder = passwordEncoder;
        this.userRepository = userRepository;
        this.roleRepository = roleRepository;
    }

    @PostConstruct
    public void run() {
        createDefaultRolesIfNotExists();
        createDefaultUserIfNotExists();
    }

    private void createDefaultRolesIfNotExists() {
        if (roleRepository.findAll().isEmpty()) {
            Role adminRole = new Role();
            adminRole.setName(Role.ROLE_ADMIN);
            adminRole.setEnabled(true);
            roleRepository.save(adminRole);
            logger.info("Created default admin role \"{}\"", Role.ROLE_ADMIN);
        }
    }

    private void createDefaultUserIfNotExists() {
        if (userRepository.findAll().isEmpty()) {
// Path: src/main/java/com/lyubenblagoev/postfixrest/entity/Role.java
// @Entity
// @Table(name = "roles")
// public class Role extends BaseEntity {
// 
//     public static final String ROLE_ADMIN = "ADMIN";
// 
//     @Column
//     private String name;
// 
//     @ManyToMany(mappedBy = "roles")
//     private List<User> users;
// 
//     public String getName() {
//         return name;
//     }
// 
//     public void setName(String name) {
//         this.name = name;
//     }
// 
//     public List<User> getUsers() {
//         return users;
//     }
// 
//     public void setUsers(List<User> users) {
//         this.users = users;
//     }
// }
// 
// Path: src/main/java/com/lyubenblagoev/postfixrest/entity/User.java
// @Entity
// @Table(name = "users")
// public class User extends BaseEntity {
// 
//     @Column(nullable = false)
//     private String email;
// 
//     @Column(nullable = false)
//     private String password;
// 
//     @OneToMany(orphanRemoval = true, cascade = CascadeType.ALL, mappedBy = "user")
//     private List<Device> devices = Collections.emptyList();
// 
//     @ManyToMany
//     @JoinTable(
//             name = "users_roles",
//             joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"),
//             inverseJoinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id")
//     )
//     private List<Role> roles;
// 
//     public User(String email, String password) {
//         super();
//         this.email = email;
//         this.password = password;
//         this.setEnabled(true);
//     }
// 
//     protected User() {
//     }
// 
//     public String getEmail() {
//         return email;
//     }
// 
//     public void setEmail(String email) {
//         this.email = email;
//     }
// 
//     public String getPassword() {
//         return password;
//     }
// 
//     public void setPassword(String password) {
//         this.password = password;
//     }
// 
//     public List<Device> getDevices() {
//         return devices;
//     }
// 
//     public void setDevices(List<Device> devices) {
//         this.devices = devices;
//     }
// 
//     public void addDevice(Device device) {
//         Objects.requireNonNull(device);
//         getDevices().add(device);
//         device.setUser(this);
//     }
// 
//     public void removeDevice(Device device) {
//         Objects.requireNonNull(device);
//         getDevices().remove(device);
//         device.setUser(null);
//     }
// 
//     public List<Role> getRoles() {
//         return roles;
//     }
// 
//     public void setRoles(List<Role> roles) {
//         this.roles = roles;
//     }
// }
// 
// Path: src/main/java/com/lyubenblagoev/postfixrest/repository/RoleRepository.java
// @Repository
// public interface RoleRepository extends JpaRepository<Role, Long> {
// 
//     List<Role> findByName(String name);
// 
// }
// 
// Path: src/main/java/com/lyubenblagoev/postfixrest/repository/UserRepository.java
// public interface UserRepository extends JpaRepository<User, Long> {
// 
//     @Query("FROM User u LEFT JOIN FETCH u.roles WHERE u.email = :email")
//     Optional<User> findByEmail(String email);
// 
// }


// Path: src/main/java/com/lyubenblagoev/postfixrest/security/DefaultAdminUserInitializer.java
import com.lyubenblagoev.postfixrest.entity.Role;
import com.lyubenblagoev.postfixrest.entity.User;
import com.lyubenblagoev.postfixrest.repository.RoleRepository;
import com.lyubenblagoev.postfixrest.repository.UserRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;


    @Value("${users.default-user.password}")
    private String defaultUserPassword;

    public DefaultAdminUserInitializer(PasswordEncoder passwordEncoder,
                                       UserRepository userRepository,
                                       RoleRepository roleRepository) {
        this.passwordEncoder = passwordEncoder;
        this.userRepository = userRepository;
        this.roleRepository = roleRepository;
    }

    @PostConstruct
    public void run() {
        createDefaultRolesIfNotExists();
        createDefaultUserIfNotExists();
    }

    private void createDefaultRolesIfNotExists() {
        if (roleRepository.findAll().isEmpty()) {
            Role adminRole = new Role();
            adminRole.setName(Role.ROLE_ADMIN);
            adminRole.setEnabled(true);
            roleRepository.save(adminRole);
            logger.info("Created default admin role \"{}\"", Role.ROLE_ADMIN);
        }
    }

    private void createDefaultUserIfNotExists() {
        if (userRepository.findAll().isEmpty()) {
            User adminUser = new User(defaultUserEmail, passwordEncoder.encode(defaultUserPassword));