package com.oguerreiro.resilient.service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.oguerreiro.resilient.domain.Unit;
import com.oguerreiro.resilient.repository.UnitRepository;
import com.oguerreiro.resilient.service.dto.UnitDTO;
import com.oguerreiro.resilient.service.mapper.UnitMapper;

/**
 * Service Implementation for managing {@link com.oguerreiro.resilient.domain.Unit}.
 */
@Service
@Transactional
public class UnitService extends AbstractResilientService<UnitDTO, Unit, Long> {
  private final UnitRepository unitRepository;
  private final UnitMapper unitMapper;

  public UnitService(UnitRepository unitRepository, UnitMapper unitMapper) {
    super(Unit.class, unitRepository, unitMapper);

    this.unitRepository = unitRepository;
    this.unitMapper = unitMapper;
  }

  /**
   * Get all the units, restricted by type.
   *
   * @return the list of entities.
   */
  @Transactional(readOnly = true)
  public List<UnitDTO> findAllByType(Long unitTypeId) {
    log.debug("Request to get all Units");
    return unitRepository.findAllByTypeWithToOneRelationships(unitTypeId).stream().map(unitMapper::toDto).collect(
        Collectors.toCollection(LinkedList::new));
  }

  /**
   * Get all the units allowed in variable
   *
   * @return the list of entities.
   */
  @Transactional(readOnly = true)
  public List<UnitDTO> findAllUnitsAllowedForVariable(Long variableId) {
    log.debug("Request to findAllUnitsAllowedForVariable");

    List<Unit> units = new ArrayList<>();
    units.addAll(unitRepository.findAllUnitsAllowedForVariable(variableId));
    units.addAll(unitRepository.findBaseUnitForVariable(variableId));

    // @formatter:off
    return units.stream()
        .sorted(Comparator.comparing(Unit::getCode)) // Sort by code
        .map(unitMapper::toDto)
        .collect(Collectors.toList());
    // @formatter:on
  }
}
