package de.ids_mannheim.korap.dao;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.util.List;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import de.ids_mannheim.korap.constant.QueryType;
import de.ids_mannheim.korap.constant.ResourceType;
import de.ids_mannheim.korap.constant.UserGroupStatus;
import de.ids_mannheim.korap.constant.PredefinedRole;
import de.ids_mannheim.korap.constant.PrivilegeType;
import de.ids_mannheim.korap.entity.QueryDO;
import de.ids_mannheim.korap.entity.Role;
import de.ids_mannheim.korap.entity.UserGroup;
import de.ids_mannheim.korap.exceptions.KustvaktException;
import de.ids_mannheim.korap.user.User;

/** Generated by Github Copilot
 * 
 */
@ExtendWith(SpringExtension.class)
@ContextConfiguration("classpath:test-config.xml")
public class QueryCaseSensitivityTest extends DaoTestBase {

    @Autowired
    private QueryDao queryDao;
    @Autowired
    private RoleDao roleDao;
    @Autowired
    private UserGroupDao userGroupDao;

    @Test
    public void retrieveQueryByName_caseInsensitive () throws KustvaktException {
        String creator = "caseUser";
        String name = "casevc";
        int id = queryDao.createQuery(name, ResourceType.PRIVATE,
                QueryType.VIRTUAL_CORPUS, User.CorpusAccess.FREE, "koral",
                "def", "desc", "status", false, creator, null, null, null);

        QueryDO created = queryDao.retrieveQueryById(id);
        assertEquals(name, created.getName());

        // lookup with different case for the query name
        QueryDO found = queryDao.retrieveQueryByName("CaseVC", creator);
        assertNotNull(found);
        assertEquals(id, found.getId());

        // cleanup
        queryDao.deleteQuery(created);
    }

    @Test
    public void retrieveHiddenGroupByQueryName_caseInsensitive () throws KustvaktException {
        String groupCreator = "groupCreator";
        // create a hidden group
        int gid = userGroupDao.createGroup("hidden-group", null, groupCreator,
                UserGroupStatus.HIDDEN);
        UserGroup group = userGroupDao.retrieveGroupById(gid, true);

        // create a query with mixed case name
        String qCreator = "queryCreator";
        String qName = "publishedvc";
        int qid = queryDao.createQuery(qName, ResourceType.PUBLISHED,
                QueryType.VIRTUAL_CORPUS, User.CorpusAccess.FREE, "koral",
                "def", "desc", "status", false, qCreator, null, null, null);
        QueryDO query = queryDao.retrieveQueryById(qid);

        // attach a role linking the group and the query
        Role r = new Role(PredefinedRole.GROUP_ADMIN, PrivilegeType.READ_MEMBER,
                group, query);
        roleDao.addRole(r);

        // lookup hidden group by query name using different case
        UserGroup found = userGroupDao.retrieveHiddenGroupByQueryName("PublishedVC");
        assertNotNull(found);
        assertEquals(gid, found.getId());

        // cleanup
        deleteUserGroup(gid, groupCreator);
        queryDao.deleteQuery(query);
    }

    @Test
    public void deleteRoleByGroupAndQuery_queryName_caseInsensitive () throws KustvaktException {
        // create a fresh group using helper
        UserGroup group = createUserGroup("del-group", "deleter");

        String qCreator = "queryCreator";
        String qName = "delvc";
        int qid = queryDao.createQuery(qName, ResourceType.PRIVATE,
                QueryType.VIRTUAL_CORPUS, User.CorpusAccess.FREE, "koral",
                "def", "desc", "status", false, qCreator, null, null, null);
        QueryDO query = queryDao.retrieveQueryById(qid);

        // add a role linking group and query
        Role r = new Role(PredefinedRole.GROUP_ADMIN, PrivilegeType.READ_MEMBER,
                group, query);
        roleDao.addRole(r);

        // ensure role exists for the query
        List<Role> rolesBefore = roleDao.retrieveRolesByQueryIdWithMembers(qid);
        assertTrue(rolesBefore.size() >= 1);

        // delete by group name and different-case query name
        roleDao.deleteRoleByGroupAndQuery(group.getName(), qCreator, "DelVC");

        List<Role> rolesAfter = roleDao.retrieveRolesByQueryIdWithMembers(qid);
        assertEquals(0, rolesAfter.size());

        // cleanup
        deleteUserGroup(group.getId(), "deleter");
        queryDao.deleteQuery(query);
    }
}
