package ru.shine.promo.service; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; import ru.shine.promo.config.AppProperties; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.util.LinkedHashSet; import java.util.Set; import java.util.regex.Pattern; @Service public class PromoCodeService { private static final Logger log = LoggerFactory.getLogger(PromoCodeService.class); private static final Pattern PROMO_CODE_PATTERN = Pattern.compile("^[a-z0-9]{8}$"); private final AppProperties appProperties; public PromoCodeService(AppProperties appProperties) { this.appProperties = appProperties; } public String normalizePromoCode(String rawPromoCode) { if (rawPromoCode == null) { return ""; } return rawPromoCode.trim().toLowerCase(); } public boolean isPromoCodeFormatValid(String promoCode) { return PROMO_CODE_PATTERN.matcher(promoCode).matches(); } public boolean isEternalPromoCode(String promoCode) { if (!appProperties.isPromoEternalCodeEnabled()) { return false; } String configured = appProperties.getPromoEternalCodeValue(); return !configured.isEmpty() && configured.equals(promoCode); } public boolean promoCodeExists(String promoCode) { Set codes = readPromoCodesFromFile(); return codes.contains(promoCode); } private Set readPromoCodesFromFile() { Path file = Path.of(appProperties.getPromoCodesFile()); if (!Files.exists(file)) { throw new PromoException(HttpStatus.INTERNAL_SERVER_ERROR, "Ошибка чтения файла промокодов"); } try { Set result = new LinkedHashSet<>(); for (String row : Files.readAllLines(file, StandardCharsets.UTF_8)) { String line = row.trim().toLowerCase(); if (line.isEmpty() || line.startsWith("#")) { continue; } if (!isPromoCodeFormatValid(line)) { log.warn("Skipped invalid promo code row in {}: {}", file, line); continue; } result.add(line); } return result; } catch (IOException e) { throw new PromoException(HttpStatus.INTERNAL_SERVER_ERROR, "Ошибка чтения файла промокодов", e); } } }