package com.oguerreiro.resilient.web.rest;

import java.io.Serializable;
import java.util.List;

import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;

import com.oguerreiro.resilient.domain.AbstractResilientEntity;
import com.oguerreiro.resilient.repository.ResilientJpaRepository;
import com.oguerreiro.resilient.service.AbstractResilientService;
import com.oguerreiro.resilient.service.criteria.AbstractCriteria;
import com.oguerreiro.resilient.service.dto.AbstractResilientDTO;
import com.oguerreiro.resilient.service.query.AbstractQueryService;

public abstract class AbstractResilientQueryResource<T extends AbstractResilientEntity<T, ID>, DTO extends AbstractResilientDTO<ID>, ID extends Serializable, C extends AbstractCriteria>
    extends AbstractResilientResource<T, DTO, ID> {

  private final AbstractQueryService<T, DTO, ID, C> domainQueryService;

  protected AbstractResilientQueryResource(Class<T> domainClass, ResilientJpaRepository<T, ID> domainRepository,
      AbstractResilientService<DTO, T, ID> domainService, AbstractQueryService<T, DTO, ID, C> domainQueryService) {
    super(domainClass, domainRepository, domainService);
    this.domainQueryService = domainQueryService;
  }

  /**
   * {@code GET  /<entity path>/criteria} : get with a criteria.
   *
   * @param  criteria the criteria which the requested entities should match.
   * @return          the {@link ResponseEntity} with status {@code 200 (OK)} and the list of entity domains in body.
   */
  @PreAuthorize("@resilientSecurity.canAccess()")
  @GetMapping("/criteria")
  public ResponseEntity<List<DTO>> getAllByCriteria(C criteria) {
    log.debug("REST request to getAllByCriteria by criteria: {}", criteria);

    List<DTO> domainList = domainQueryService.findByCriteria(criteria, this.getAllSort());
    return ResponseEntity.ok().body(domainList);
  }
}
