package de.votian.services.service;

import de.votian.services.config.ParameterKeys;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.jdbc.core.JdbcTemplate;

import java.time.LocalDate;

import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

@SuppressWarnings("null")
class LegacyXmlSystemAuthServiceTest {

    private JdbcTemplate jdbcTemplate;
    private ParameterService parameterService;
    private LegacyXmlSystemAuthService service;

    @BeforeEach
    void setUp() {
        jdbcTemplate = mock(JdbcTemplate.class);
        parameterService = mock(ParameterService.class);
        service = new LegacyXmlSystemAuthService(jdbcTemplate, parameterService);
    }

    @Test
    void authenticateAcceptsMatchingSystemSessionAndPassphrase() {
        String salt = "34a78d91s83g";
        String passphrase = buildPassphrase(salt, LocalDate.now());

        when(parameterService.getParameterValue(ParameterKeys.GLOBAL_UNIQUE_DB_INSTANCE_NO, 0L)).thenReturn("100");
        when(parameterService.getParameterValue(ParameterKeys.GLOBAL_SESSION_SYSTEM_ID, 0L)).thenReturn("42");
        when(parameterService.getParameterValue(ParameterKeys.GLOBAL_SESSION_SALT, 0L)).thenReturn(salt);
        when(jdbcTemplate.queryForObject(anyString(), eq(Integer.class), eq("100"), eq("42"), eq("SESSION")))
                .thenReturn(1);

        service.authenticate("SESSION", passphrase);
    }

    @Test
    void authenticateRejectsWrongPassphrase() {
        when(parameterService.getParameterValue(ParameterKeys.GLOBAL_UNIQUE_DB_INSTANCE_NO, 0L)).thenReturn("100");
        when(parameterService.getParameterValue(ParameterKeys.GLOBAL_SESSION_SYSTEM_ID, 0L)).thenReturn("42");
        when(parameterService.getParameterValue(ParameterKeys.GLOBAL_SESSION_SALT, 0L)).thenReturn("34a78d91s83g");
        when(jdbcTemplate.queryForObject(anyString(), eq(Integer.class), eq("100"), eq("42"), eq("SESSION")))
                .thenReturn(1);

        assertThatThrownBy(() -> service.authenticate("SESSION", "invalid"))
                .isInstanceOf(LegacyXmlRequestException.class)
                .extracting("errorCode")
                .isEqualTo("101");
    }

    private String buildPassphrase(String salt, LocalDate date) {
        String ymd = date.toString().replace("-", "");
        String dd = ymd.substring(6, 8);
        String mm = ymd.substring(4, 6);
        String yymmdd = ymd.substring(2);
        return dd + salt.substring(5, 8) + mm + salt.substring(0, 5) + yymmdd + salt.substring(8, 12);
    }
}
