package com.hitcommunications.servermanager.services; import com.hitcommunications.servermanager.mappers.ServersMapper; import com.hitcommunications.servermanager.model.Servers; import com.hitcommunications.servermanager.model.dtos.BulkServerImportResponse; import com.hitcommunications.servermanager.model.dtos.BulkServerImportResponse.FailedRow; import com.hitcommunications.servermanager.model.dtos.NewServerDTO; import com.hitcommunications.servermanager.model.dtos.ServerDTO; import com.hitcommunications.servermanager.model.enums.Applications; import com.hitcommunications.servermanager.model.enums.DatabaseType; import com.hitcommunications.servermanager.model.enums.ServersType; import com.hitcommunications.servermanager.repositories.ServersRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.ArrayList; @Service @RequiredArgsConstructor public class ServersService { private final ServersMapper mapper; private final ServersRepository repo; public ServerDTO create(NewServerDTO createDTO) { // Check if server with same IP and port already exists repo.findByIpAndPort(createDTO.ip(), createDTO.port()).ifPresent(entity -> { throw new RuntimeException("Server already exists with IP: " + createDTO.ip() + " and port: " + createDTO.port()); }); Servers entity = mapper.toEntity(createDTO); entity = repo.save(entity); return mapper.toDTO(entity); } public ServerDTO getById(String id) { return repo.findById(id) .map(mapper::toDTO) .orElseThrow(() -> new RuntimeException("Server not found with id: " + id)); } public ServerDTO getByName(String name) { return repo.findByName(name) .map(mapper::toDTO) .orElseThrow(() -> new RuntimeException("Server not found with name: " + name)); } public List getByType(ServersType type) { return repo.findByType(type) .stream() .map(mapper::toDTO) .toList(); } public Map countAllByType() { Map response = new HashMap<>(); for(ServersType type : ServersType.values()) { response.put(type, repo.countAllByType(type)); } return response; } public List getByApplication(Applications application) { return repo.findByApplication(application) .stream() .map(mapper::toDTO) .toList(); } public BulkServerImportResponse bulkCreate(MultipartFile file) { List failures = new ArrayList<>(); int succeeded = 0; int processed = 0; try (BufferedReader reader = new BufferedReader(new InputStreamReader(file.getInputStream(), StandardCharsets.UTF_8))) { String line; int lineNumber = 0; while ((line = reader.readLine()) != null) { lineNumber++; if (line.isBlank()) { continue; } String[] columns = parseColumns(line); if (isHeaderRow(columns)) { continue; } processed++; try { NewServerDTO dto = toNewServerDTO(columns); create(dto); succeeded++; } catch (Exception ex) { failures.add(new FailedRow(lineNumber, ex.getMessage(), line)); } } } catch (IOException e) { throw new RuntimeException("Erro ao ler arquivo CSV.", e); } int failed = failures.size(); return new BulkServerImportResponse(processed, succeeded, failed, failures); } private String[] parseColumns(String line) { String[] rawColumns = line.split(";"); String[] columns = new String[rawColumns.length]; for (int i = 0; i < rawColumns.length; i++) { columns[i] = rawColumns[i].trim(); } return columns; } private NewServerDTO toNewServerDTO(String[] columns) { if (columns.length < 8) { throw new IllegalArgumentException("Linha incompleta. Esperado 8 colunas."); } String name = columns[0]; String ip = columns[1]; Integer port = Integer.parseInt(columns[2]); String user = columns[3]; String password = columns[4]; ServersType type = ServersType.valueOf(columns[5].toUpperCase()); Applications application = Applications.valueOf(columns[6].toUpperCase()); DatabaseType dbType = DatabaseType.valueOf(columns[7].toUpperCase()); return new NewServerDTO(name, ip, port, user, password, type, application, dbType); } private boolean isHeaderRow(String[] columns) { if (columns.length < 8) { return false; } return "name".equalsIgnoreCase(columns[0]) && "ip".equalsIgnoreCase(columns[1]) && "port".equalsIgnoreCase(columns[2]); } public List getAll() { return repo.findAll() .stream() .map(mapper::toDTO) .toList(); } public ServerDTO update(String id, NewServerDTO updateDTO) { Servers entity = repo.findById(id) .orElseThrow(() -> new RuntimeException("Server not found with id: " + id)); // Check if IP/port combination already exists (excluding current server) repo.findByIpAndPort(updateDTO.ip(), updateDTO.port()).ifPresent(existingServer -> { if (!existingServer.getId().equals(id)) { throw new RuntimeException("Server already exists with IP: " + updateDTO.ip() + " and port: " + updateDTO.port()); } }); mapper.partialUpdate(updateDTO, entity); entity = repo.save(entity); return mapper.toDTO(entity); } public void delete(String id) { if (!repo.existsById(id)) { throw new RuntimeException("Server not found with id: " + id); } repo.deleteById(id); } }