package com.company.mtentlog.user;

import com.company.mtentlog.entity.Issue;
import com.company.mtentlog.entity.User;
import com.company.mtentlog.test_support.AuthenticatedAsAdmin;
import io.jmix.audit.EntityLog;
import io.jmix.core.DataManager;
import io.jmix.core.Sort;
import io.jmix.core.TimeSource;
import io.jmix.core.event.AttributeChanges;
import io.jmix.core.security.SystemAuthenticator;
import io.jmix.core.security.UserRepository;
import io.jmix.multitenancy.entity.Tenant;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.transaction.support.TransactionTemplate;

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

/**
 * Sample integration test for the User entity.
 */
@SpringBootTest
@ExtendWith(AuthenticatedAsAdmin.class)
public class MiscTest {

    @Autowired
    DataManager dataManager;

    @Autowired
    PasswordEncoder passwordEncoder;

    @Autowired
    UserRepository userRepository;

    User savedUser;
    @Autowired
    private SystemAuthenticator systemAuthenticator;
    @Autowired
    private TimeSource timeSource;

    @Test
    void test_userSaveAndLoad() {
        // Create and save a new User
        User user = dataManager.create(User.class);
        user.setUsername("test-user-" + System.currentTimeMillis());
        user.setPassword(passwordEncoder.encode("test-passwd"));
        savedUser = dataManager.save(user);

        // Check the new user can be loaded
        User loadedUser = dataManager.load(User.class).id(user.getId()).one();
        assertThat(loadedUser).isEqualTo(user);

        // Check the new user is available through UserRepository
        UserDetails userDetails = userRepository.loadUserByUsername(user.getUsername());
        assertThat(userDetails).isEqualTo(user);
    }

    @Test
    void test_tenants() {
        List<Tenant> tenants = dataManager.load(Tenant.class).all().list();
        System.out.println(tenants.size() + " tenants exists");
    }

    @Test
    void test_issueLog() {
        List<Issue> issues = dataManager.load(Issue.class).all().sort(Sort.by("name")).list();
        System.out.println(issues.size() + " issues exists");
        Issue one = issues.get(0);

        systemAuthenticator.runWithUser("t1|test_1", () -> {
            one.setDetails(one.getDetails() + "_C");
            dataManager.save(one);
            Issue another = dataManager.create(Issue.class);
            another.setName("five_" + timeSource.currentTimestamp());
            another.setDetails("someDetails");
            dataManager.save(another);
        });
    }

    @AfterEach
    void tearDown() {
        if (savedUser != null)
            dataManager.remove(savedUser);
    }
}
