package carldav.bootstrap;

import carldav.entity.User;
import carldav.repository.UserRepository;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.security.authentication.encoding.PasswordEncoder;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import static org.slf4j.LoggerFactory.getLogger;

/**
 * @author Kamill Sokol
 */
@Component
public class AdminUserCreator implements ApplicationListener<ContextRefreshedEvent> {

    private static final Logger LOG = getLogger(AdminUserCreator.class);

    private final UserRepository userRepository;
    private final PasswordEncoder passwordEncoder;

    private final String adminName;
    private final String adminPassword;

    public AdminUserCreator(UserRepository userRepository, PasswordEncoder passwordEncoder, @Value("${carldav.admin.name}") String adminName, @Value("${carldav.admin.password}") String adminPassword) {
        Assert.notNull(userRepository, "userRepository is null");
        Assert.notNull(passwordEncoder, "passwordEncoder is null");
        Assert.notNull(adminName, "adminName is null");
        Assert.notNull(adminPassword, "adminPassword is null");
        this.userRepository = userRepository;
        this.passwordEncoder = passwordEncoder;
        this.adminName = adminName;
        this.adminPassword = adminPassword;
    }

    @Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
        LOG.info("checking for admin user with name {}", adminName);

        User admin = userRepository.findByEmailIgnoreCase(adminName);

        if(admin != null) {
            LOG.info("admin user found. checking admin user password for '{}'", adminName);

            if(!admin.getPassword().equals(adminPassword)) {
                LOG.info("admin user password changed. setting to '{}", adminPassword);
                admin.setPassword(passwordEncoder.encodePassword(adminPassword, null));
                userRepository.save(admin);
                LOG.info("admin user password changed");
            }
        } else {
            LOG.info("admin user '{}' not found creating", adminName);

            admin = new User();
            admin.setEmail(adminName);
            admin.setPassword(passwordEncoder.encodePassword(adminPassword, null));
            admin.setRole("ROLE_ADMIN");
            admin.setLocked(false);
            userRepository.save(admin);
        }

        LOG.info("admin user '{}:{}'", admin.getEmail(), admin.getPassword());
    }
}

@@ -462,16 +462,40 @@
 ssert;%0A%0A
+import java.util.UUID;%0A%0A
 import s
@@ -881,38 +881,32 @@
 me;%0A    private 
-final 
 String adminPass
@@ -1086,16 +1086,21 @@
 password
+:null
 %7D%22) Stri
@@ -1264,31 +1264,31 @@
      Assert.
-notNull
+hasText
 (adminName, 
@@ -1324,23 +1324,23 @@
  Assert.
-notNull
+hasText
 (adminPa
@@ -1783,32 +1783,144 @@
 se(adminName);%0A%0A
+        if(%22null%22.equals(adminPassword)) %7B%0A            adminPassword = UUID.randomUUID().toString();%0A        %7D%0A%0A
         if(admin
@@ -2154,16 +2154,17 @@
 g to '%7B%7D
+'
 %22, admin
@@ -2811,28 +2811,24 @@
 ), admin
-.get
 Password
 ());%0A   
@@ -2819,18 +2819,16 @@
 Password
-()
 );%0A    %7D

create random admin user password on every startup as long as configuration property "carldav.admin.password" has not been set