package com.oguerreiro.resilient.web.rest;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Sort;
import org.springframework.http.ContentDisposition;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.oguerreiro.resilient.domain.Variable;
import com.oguerreiro.resilient.repository.VariableRepository;
import com.oguerreiro.resilient.service.VariableService;
import com.oguerreiro.resilient.service.criteria.VariableCriteria;
import com.oguerreiro.resilient.service.dto.UnitDTO;
import com.oguerreiro.resilient.service.dto.VariableDTO;
import com.oguerreiro.resilient.service.query.VariableQueryService;

import tech.jhipster.web.util.ResponseUtil;

/**
 * REST controller for managing {@link com.oguerreiro.resilient.domain.Variable}.
 */
@RestController
@RequestMapping("/api/variables")
public class VariableResource extends AbstractResilientQueryResource<Variable, VariableDTO, Long, VariableCriteria> {

  private final Logger log = LoggerFactory.getLogger(VariableResource.class);

  private static final String ENTITY_NAME = "variable";

  private final VariableService variableService;

  private final VariableQueryService variableQueryService;

  public VariableResource(VariableService variableService, VariableRepository variableRepository,
      VariableQueryService variableQueryService) {
    super(Variable.class, variableRepository, variableService, variableQueryService);
    this.variableService = variableService;
    this.variableQueryService = variableQueryService;
  }

  /* Abstract methods impl*/
  @Override
  protected String getEntityName() {
    return ENTITY_NAME;
  }

  @Override
  protected Sort getAllSort() {
    return Sort.by(Sort.Order.asc("code"));
  }

  /* Custom VariableResource endpoints */
  /**
   * {@code GET  /variables/count} : count all the variables.
   *
   * @param  criteria the criteria which the requested entities should match.
   * @return          the {@link ResponseEntity} with status {@code 200 (OK)} and the count in body.
   */
  @PreAuthorize("@resilientSecurity.canAccess('READ', 'com.oguerreiro.resilient.domain.Variable')")  // Inventory, delegates permission to Variable
  @GetMapping("/count")
  public ResponseEntity<Long> countVariables(VariableCriteria criteria) {
    log.debug("REST request to count Variables by criteria: {}", criteria);
    return ResponseEntity.ok().body(variableQueryService.countByCriteria(criteria));
  }

  @PreAuthorize("@resilientSecurity.canAccess('READ', 'com.oguerreiro.resilient.domain.Variable')")  // Inventory, delegates permission to Variable
  @GetMapping("/{id}/baseUnit")
  public ResponseEntity<UnitDTO> getVariableBaseUnit(@PathVariable("id") Long id) {
    log.debug("REST request to getVariableBaseUnit : {}", id);

    return ResponseUtil.wrapOrNotFound(variableService.getVariableBaseUnit(id));
  }

  @PreAuthorize("@resilientSecurity.canAccess('READ', 'com.oguerreiro.resilient.domain.Variable')")  // Inventory, delegates permission to Variable
  @GetMapping("/forManualInput")
  public ResponseEntity<List<VariableDTO>> getVariableforManualInput() {
    log.debug("REST request to getVariableforManualInput");

    List<VariableDTO> domainList = variableService.findVariableForManualInput();
    return ResponseEntity.ok().body(domainList);
  }

  @GetMapping("/export")
  public ResponseEntity<byte[]> exportVariables() {
    log.debug("REST request to export Variables: {}");

    byte[] fileContent = this.variableService.exportVariables();

    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
    headers.setContentDisposition(ContentDisposition.attachment().filename("report.xlsx").build());

    return new ResponseEntity<>(fileContent, headers, HttpStatus.OK);
  }
}
