content: package io.aiven.klaw.helpers.db.rdbms;
  
  import static io.aiven.klaw.error.KlawErrorMessages.DELETE_REQ_ERR;
  
  import io.aiven.klaw.dao.*;
  import io.aiven.klaw.model.enums.ApiResultStatus;
  import io.aiven.klaw.model.enums.RequestStatus;
  import io.aiven.klaw.repository.*;
  import jakarta.transaction.Transactional;
  import java.util.List;
  import java.util.Optional;
  import lombok.extern.slf4j.Slf4j;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.context.annotation.Configuration;
  
  @Configuration
  @Slf4j
  public class DeleteDataJdbc {
  
    @Autowired(required = false)
    TopicRequestsRepo topicRequestsRepo;
  
    @Autowired(required = false)
    OperationalRequestsRepo operationalRequestsRepo;
  
    @Autowired(required = false)
    private TopicRepo topicRepo;
  
    @Autowired(required = false)
    KwKafkaConnectorRequestsRepo kafkaConnectorRequestsRepo;
  
    @Autowired(required = false)
    private KwKafkaConnectorRepo kafkaConnectorRepo;
  
    @Autowired(required = false)
    SchemaRequestRepo schemaRequestRepo;
  
    @Autowired(required = false)
    MessageSchemaRepo messageSchemaRepo;
  
    @Autowired(required = false)
    EnvRepo envRepo;
  
    @Autowired(required = false)
    KwClusterRepo kwClusterRepo;
  
    @Autowired(required = false)
    TeamRepo teamRepo;
  
    @Autowired(required = false)
    AclRequestsRepo aclRequestsRepo;
  
    @Autowired(required = false)
    AclRepo aclRepo;
  
    @Autowired(required = false)
    UserInfoRepo userInfoRepo;
  
    @Autowired(required = false)
    private RegisterInfoRepo registerInfoRepo;
  
    @Autowired(required = false)
    private KwRolesPermsRepo kwRolesPermsRepo;
  
    @Autowired(required = false)
    private KwPropertiesRepo kwPropertiesRepo;
  
    @Autowired(required = false)
    private TenantRepo tenantRepo;
  
    public DeleteDataJdbc() {}
  
    public DeleteDataJdbc(
        TopicRequestsRepo topicRequestsRepo,
        SchemaRequestRepo schemaRequestRepo,
        EnvRepo envRepo,
        TeamRepo teamRepo,
        AclRequestsRepo aclRequestsRepo,
        AclRepo aclRepo,
        UserInfoRepo userInfoRepo,
        RegisterInfoRepo registerInfoRepo) {
      this.topicRequestsRepo = topicRequestsRepo;
      this.schemaRequestRepo = schemaRequestRepo;
      this.envRepo = envRepo;
      this.teamRepo = teamRepo;
      this.aclRepo = aclRepo;
      this.aclRequestsRepo = aclRequestsRepo;
      this.userInfoRepo = userInfoRepo;
      this.registerInfoRepo = registerInfoRepo;
    }
  
    public String deleteConnectorRequest(int connectorId, int tenantId) {
      log.debug("deleteConnectorRequest {} {}", connectorId, tenantId);
      KafkaConnectorRequestID kafkaConnectorRequestID = new KafkaConnectorRequestID();
      kafkaConnectorRequestID.setConnectorId(connectorId);
      kafkaConnectorRequestID.setTenantId(tenantId);
  
      Optional<KafkaConnectorRequest> topicReq =
          kafkaConnectorRequestsRepo.findById(kafkaConnectorRequestID);
      if (topicReq.isPresent()) {
        topicReq.get().setRequestStatus(RequestStatus.DELETED.value);
        kafkaConnectorRequestsRepo.save(topicReq.get());
      }
      return ApiResultStatus.SUCCESS.value;
    }
  
    public String deleteTopicRequest(int topicId, String userName, int tenantId) {
      log.debug("deleteTopicRequest {}", topicId);
  
      TopicRequestID topicRequestID = new TopicRequestID();
      topicRequestID.setTenantId(tenantId);
      topicRequestID.setTopicid(topicId);
  
      Optional<TopicRequest> topicReq = topicRequestsRepo.findById(topicRequestID);
      // UserName is transient and is not set in the database but the requestor is. Both are set to
      // the userName when the request is created.
      if (topicReq.isPresent() && topicReq.get().getRequestor().equals(userName)) {
        topicReq.get().setRequestStatus(RequestStatus.DELETED.value);
        topicRequestsRepo.save(topicReq.get());
        return ApiResultStatus.SUCCESS.value;
      }
      return ApiResultStatus.FAILURE.value + DELETE_REQ_ERR;
    }
  
    public String deleteOperationalRequest(int operationalReqId, String userName, int tenantId) {
      log.debug("deleteOperationalRequest {}", operationalReqId);
  
      OperationalRequestID operationalRequestID = new OperationalRequestID();
      operationalRequestID.setTenantId(tenantId);
      operationalRequestID.setReqId(operationalReqId);
  
      Optional<OperationalRequest> operationalRequest =
          operationalRequestsRepo.findById(operationalRequestID);
      // UserName is transient and is not set in the database but the requestor is. Both are set to
      // the userName when the request is created.
      if (operationalRequest.isPresent()
          && operationalRequest.get().getRequestor().equals(userName)) {
        operationalRequest.get().setRequestStatus(RequestStatus.DELETED.value);
        operationalRequestsRepo.save(operationalRequest.get());
        return ApiResultStatus.SUCCESS.value;
      }
      return ApiResultStatus.FAILURE.value + DELETE_REQ_ERR;
    }
  
    public String deleteTopic(int topicId, int tenantId) {
      log.debug("deleteTopic {}", topicId);
      TopicID topicID = new TopicID();
      topicID.setTenantId(tenantId);
      topicID.setTopicid(topicId);
  
      Optional<Topic> topicReq = topicRepo.findById(topicID);
      topicReq.ifPresent(topic -> topicRepo.delete(topic));
      return ApiResultStatus.SUCCESS.value;
    }
  
    public String deleteConnector(int connectorId, int tenantId) {
      log.debug("deleteConnector {}", connectorId);
      KwKafkaConnectorID kwKafkaConnectorID = new KwKafkaConnectorID();
      kwKafkaConnectorID.setConnectorId(connectorId);
      kwKafkaConnectorID.setTenantId(tenantId);
  
      Optional<KwKafkaConnector> topicReq = kafkaConnectorRepo.findById(kwKafkaConnectorID);
      topicReq.ifPresent(topic -> kafkaConnectorRepo.delete(topic));
      return ApiResultStatus.SUCCESS.value;
    }
  
    public String deleteSchemaRequest(int avroSchemaId, String userName, int tenantId) {
      log.debug("deleteSchemaRequest {}", avroSchemaId);
      SchemaRequestID schemaRequestID = new SchemaRequestID(avroSchemaId, tenantId);
      Optional<SchemaRequest> schemaReq = schemaRequestRepo.findById(schemaRequestID);
      if (schemaReq.isPresent() && schemaReq.get().getRequestor().equals(userName)) {
        schemaReq.get().setRequestStatus(RequestStatus.DELETED.value);
        schemaRequestRepo.save(schemaReq.get());
        return ApiResultStatus.SUCCESS.value;
      }
  
      return ApiResultStatus.FAILURE.value + DELETE_REQ_ERR;
    }
  
    public String deleteAclRequest(int aclId, String userName, int tenantId) {
      log.debug("deleteAclRequest {}", aclId);
      AclRequestID aclRequestID = new AclRequestID();
      aclRequestID.setReq_no(aclId);
      aclRequestID.setTenantId(tenantId);
      Optional<AclRequests> optAclRequests = aclRequestsRepo.findById(aclRequestID);
      if (optAclRequests.isPresent() && optAclRequests.get().getRequestor().equals(userName)) {
        optAclRequests.get().setRequestStatus(RequestStatus.DELETED.value);
        aclRequestsRepo.save(optAclRequests.get());
        return ApiResultStatus.SUCCESS.value;
      }
  
      return ApiResultStatus.FAILURE.value + DELETE_REQ_ERR;
    }
  
    public String deleteEnvironment(String envId, int tenantId) {
      log.debug("deleteEnvironment {}", envId);
      EnvID envID = new EnvID();
      envID.setId(envId);
      envID.setTenantId(tenantId);
      Optional<Env> env = envRepo.findById(envID);
  
      if (env.isPresent()) {
        envRepo.delete(env.get());
        return ApiResultStatus.SUCCESS.value;
      } else {
        return ApiResultStatus.FAILURE.value;
      }
    }
  
    public String deleteCluster(int clusterId, int tenantId) {
      log.debug("deleteCluster {}", clusterId);
      KwClusters clusters = new KwClusters();
      clusters.setClusterId(clusterId);
      clusters.setTenantId(tenantId);
  
      List<Env> allAssociatedEnvs = envRepo.findAllByClusterIdAndTenantId(clusterId, tenantId);
      KwClusterID kwClusterID = new KwClusterID();
      kwClusterID.setClusterId(clusterId);
      kwClusterID.setTenantId(tenantId);
  
      if (kwClusterRepo.findById(kwClusterID).isPresent()) {
        kwClusterRepo.delete(clusters);
        envRepo.deleteAll(allAssociatedEnvs);
        return ApiResultStatus.SUCCESS.value;
      } else {
        return ApiResultStatus.FAILURE.value;
      }
    }
  
    public String deleteUserRequest(String userId) {
      log.debug("deleteUserRequest {}", userId);
      UserInfo user = new UserInfo();
      user.setUsername(userId);
      userInfoRepo.delete(user);
  
      // if the record exists in kwregisterusers, delete it
      Optional<RegisterUserInfo> registerUserInfo = registerInfoRepo.findByUsername(userId);
      registerUserInfo.ifPresent(userInfo -> registerInfoRepo.delete(userInfo));
  
      return ApiResultStatus.SUCCESS.value;
    }
  
    public String deleteTeamRequest(Integer teamId, int tenantId) {
      log.debug("deleteTeamRequest {}", teamId);
      Team team = new Team();
      team.setTeamId(teamId);
      team.setTenantId(tenantId);
  
      teamRepo.delete(team);
      return ApiResultStatus.SUCCESS.value;
    }
  
    // the actual req of Acl stored in otherParams of AclReq
    public String deletePrevAclRecs(AclRequests aclsToBeDeleted) {
  
      log.debug("deletePrevAclRecs {}", aclsToBeDeleted.getOtherParams());
      AclID aclID = new AclID();
      aclID.setReq_no(Integer.parseInt(aclsToBeDeleted.getOtherParams()));
      aclID.setTenantId(aclsToBeDeleted.getTenantId());
  
      Optional<Acl> acl = aclRepo.findById(aclID);
      acl.ifPresent(value -> aclRepo.delete(value));
  
      return ApiResultStatus.SUCCESS.value;
    }
  
    public String deleteAclSubscriptionRequest(int req_no, int tenantId) {
      log.debug("deleteAclSubscriptionRequest {}", req_no);
      AclID aclID = new AclID();
      aclID.setReq_no(req_no);
      aclID.setTenantId(tenantId);
  
      Optional<Acl> aclRec = aclRepo.findById(aclID);
      aclRec.ifPresent(acl -> aclRepo.delete(acl));
  
      return ApiResultStatus.SUCCESS.value;
    }
  
    @Transactional
    public CRUDResponse<Topic> deleteTopics(Topic topic) {
      log.debug("deleteTopics {}", topic.getTopicname());
      topicRepo.deleteByTopicnameAndEnvironmentAndTenantId(
          topic.getTopicname(), topic.getEnvironment(), topic.getTenantId());
      return CRUDResponse.ok(List.of(topic));
    }
  
    @Transactional
    public void deleteConnectors(KwKafkaConnector connector) {
      log.debug("deleteConnectors {}", connector.getConnectorName());
      kafkaConnectorRepo.deleteByConnectorNameAndEnvironmentAndTenantId(
          connector.getConnectorName(), connector.getEnvironment(), connector.getTenantId());
    }
  
    @Transactional
    public String deleteRole(String roleId, int tenantId) {
      kwRolesPermsRepo.deleteByRoleIdAndTenantId(roleId, tenantId);
  
      return ApiResultStatus.SUCCESS.value;
    }
  
    @Transactional
    public String deleteAllUsers(int tenantId) {
      userInfoRepo.deleteByTenantId(tenantId);
      registerInfoRepo.deleteByTenantId(tenantId);
      return ApiResultStatus.SUCCESS.value;
    }
  
    @Transactional
    public String deleteAllTeams(int tenantId) {
      teamRepo.deleteByTenantId(tenantId);
      return ApiResultStatus.SUCCESS.value;
    }
  
    @Transactional
    public String deleteAllEnvs(int tenantId) {
      envRepo.deleteByTenantId(tenantId);
      return ApiResultStatus.SUCCESS.value;
    }
  
    @Transactional
    public String deleteAllClusters(int tenantId) {
      kwClusterRepo.deleteByTenantId(tenantId);
      return ApiResultStatus.SUCCESS.value;
    }
  
    @Transactional
    public String deleteAllRolesPerms(int tenantId) {
      kwRolesPermsRepo.deleteByTenantId(tenantId);
      return ApiResultStatus.SUCCESS.value;
    }
  
    @Transactional
    public String deleteAllKwProps(int tenantId) {
      kwPropertiesRepo.deleteByTenantId(tenantId);
      return ApiResultStatus.SUCCESS.value;
    }
  
    public String deleteTenant(int tenantId) {
      KwTenants kwTenants = new KwTenants();
      kwTenants.setTenantId(tenantId);
      tenantRepo.delete(kwTenants);
      return ApiResultStatus.SUCCESS.value;
    }
  
    @Transactional
    public String deleteTxnData(int tenantId) {
      topicRequestsRepo.deleteByTenantId(tenantId);
      topicRepo.deleteByTenantId(tenantId);
  
      aclRequestsRepo.deleteByTenantId(tenantId);
      aclRepo.deleteByTenantId(tenantId);
  
      schemaRequestRepo.deleteByTenantId(tenantId);
      messageSchemaRepo.deleteByTenantId(tenantId);
  
      kafkaConnectorRepo.deleteByTenantId(tenantId);
      kafkaConnectorRequestsRepo.deleteByTenantId(tenantId);
  
      return ApiResultStatus.SUCCESS.value;
    }
  
    @Transactional
    public void deleteSchemas(Topic topicObj) {
      messageSchemaRepo.deleteByTenantIdAndTopicnameAndEnvironment(
          topicObj.getTenantId(), topicObj.getTopicname(), topicObj.getEnvironment());
    }
  
    @Transactional
    public void deleteSchemasWithOptions(int tenantId, String topicName, String schemaEnv) {
      messageSchemaRepo.deleteByTenantIdAndTopicnameAndEnvironment(tenantId, topicName, schemaEnv);
    }
  
    public String deleteAcls(List<Acl> listDeleteAcls, int tenantId) {
      listDeleteAcls.forEach(
          a -> {
            AclID aclID = new AclID(a.getReq_no(), tenantId);
            Optional<Acl> optionalAcl = aclRepo.findById(aclID);
            optionalAcl.ifPresent(acl -> aclRepo.delete(acl));
          });
      return ApiResultStatus.SUCCESS.value;
    }
  }
  