package io.aiven.klaw.helpers.db.rdbms;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;

import io.aiven.klaw.UtilMethods;
import io.aiven.klaw.dao.AclRequestID;
import io.aiven.klaw.dao.AclRequests;
import io.aiven.klaw.dao.Env;
import io.aiven.klaw.dao.EnvID;
import io.aiven.klaw.dao.SchemaRequest;
import io.aiven.klaw.dao.SchemaRequestID;
import io.aiven.klaw.dao.TopicRequest;
import io.aiven.klaw.dao.TopicRequestID;
import io.aiven.klaw.model.enums.ApiResultStatus;
import io.aiven.klaw.model.enums.RequestStatus;
import io.aiven.klaw.repository.*;
import java.util.Optional;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.springframework.test.context.junit.jupiter.SpringExtension;

@ExtendWith(SpringExtension.class)
public class DeleteDataJdbcTest {

  private DeleteDataJdbc deleteDataJdbc;

  @Mock private TopicRequestsRepo topicRequestsRepo;

  @Mock SchemaRequestRepo schemaRequestRepo;

  @Mock EnvRepo envRepo;
  @Mock TeamRepo teamRepo;

  @Mock AclRequestsRepo aclRequestsRepo;

  @Mock AclRepo aclRepo;

  @Mock UserInfoRepo userInfoRepo;

  @Mock RegisterInfoRepo registerUserInfoRepo;

  private UtilMethods utilMethods;

  @BeforeEach
  public void setUp() {
    deleteDataJdbc =
        new DeleteDataJdbc(
            topicRequestsRepo,
            schemaRequestRepo,
            envRepo,
            teamRepo,
            aclRequestsRepo,
            aclRepo,
            userInfoRepo,
            registerUserInfoRepo);
    utilMethods = new UtilMethods();
  }

  @Test
  public void deleteTopicRequest_Failure() {
    String result = deleteDataJdbc.deleteTopicRequest(1001, "uiuser1", 1);
    assertThat(result).contains(ApiResultStatus.FAILURE.value);
  }

  @Test
  public void deleteTopicRequest() {
    TopicRequestID id = new TopicRequestID(1010, 1);
    when(topicRequestsRepo.findById(eq(id)))
        .thenReturn(createTopicRequest("uiuser1", RequestStatus.CREATED));
    String result = deleteDataJdbc.deleteTopicRequest(1010, "uiuser1", 1);
    assertThat(result).contains(ApiResultStatus.SUCCESS.value);
  }

  private Optional<TopicRequest> createTopicRequest(String userName, RequestStatus status) {
    TopicRequest req = new TopicRequest();
    req.setRequestor(userName);
    req.setRequestStatus(status.value);
    return Optional.of(req);
  }

  @Test
  public void deleteSchemaRequest() {
    SchemaRequest req = new SchemaRequest();
    req.setRequestor("uiuser1");
    req.setReq_no(1001);
    when(schemaRequestRepo.findById(new SchemaRequestID(1001, 1))).thenReturn(Optional.of(req));
    String result = deleteDataJdbc.deleteSchemaRequest(1001, "uiuser1", 1);
    assertThat(result).isEqualTo(ApiResultStatus.SUCCESS.value);
  }

  @Test
  public void deleteAclRequest() {
    AclRequests req = new AclRequests();
    req.setRequestor("uiuser1");
    req.setReq_no(1001);
    when(aclRequestsRepo.findById(new AclRequestID(1001, 1))).thenReturn(Optional.of(req));
    String result = deleteDataJdbc.deleteAclRequest(1001, "uiuser1", 1);
    assertThat(result).isEqualTo(ApiResultStatus.SUCCESS.value);
  }

  @Test
  public void deleteEnvironmentRequest() {
    String clusterId = "1";
    Env envObj = new Env();
    EnvID env = new EnvID();
    env.setId(clusterId);
    env.setTenantId(101);
    env.setId("1");
    when(envRepo.findById(env)).thenReturn(java.util.Optional.of(envObj));
    String result = deleteDataJdbc.deleteEnvironment("1", 101);
    assertThat(result).isEqualTo(ApiResultStatus.SUCCESS.value);
  }

  @Test
  public void deleteEnvironmentThatDoesNotExistRequest() {
    String clusterId = "1";
    when(envRepo.findById(any())).thenReturn(java.util.Optional.empty());
    String result = deleteDataJdbc.deleteEnvironment("1", 101);
    assertThat(result).isEqualTo(ApiResultStatus.FAILURE.value);
  }

  @Test
  public void deleteUserRequest() {
    String result = deleteDataJdbc.deleteUserRequest("uiuser1");
    assertThat(result).isEqualTo(ApiResultStatus.SUCCESS.value);
  }

  @Test
  public void deleteTeamRequest() {
    String result = deleteDataJdbc.deleteTeamRequest(1, 1);
    assertThat(result).isEqualTo(ApiResultStatus.SUCCESS.value);
  }

  @Test
  public void deletePrevAclRecs() {
    when(aclRepo.findAllByTenantId(101)).thenReturn(utilMethods.getAllAcls());

    String result = deleteDataJdbc.deletePrevAclRecs(utilMethods.getAclRequest("testtopic"));
    assertThat(result).isEqualTo(ApiResultStatus.SUCCESS.value);
  }
}
