package net.buycraft.plugin.shared.util; import com.google.common.collect.ImmutableList; import net.buycraft.plugin.data.Coupon; import java.math.BigDecimal; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.Random; import java.util.concurrent.TimeUnit; public class CouponUtil { private static final String ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; private static final Random RANDOM = new Random(); public static long parseDuration(String text) { // Given a string like 1w3d4h5m, we will return a millisecond duration long result = 0; int numIdx = 0; for (int i = 0; i < text.length(); i++) { char at = text.charAt(i); if (at == 'd' || at == 'w' || at == 'm' || at == 'h') { String ns = text.substring(numIdx, i); numIdx = i + 1; if (ns.isEmpty()) { continue; } int n = Integer.parseInt(ns); switch (at) { case 'd': result += TimeUnit.DAYS.toMillis(n); break; case 'w': result += TimeUnit.DAYS.toMillis(n * 7); break; case 'h': result += TimeUnit.HOURS.toMillis(n); break; case 'm': result += TimeUnit.MINUTES.toMillis(n); break; } } else if (!Character.isDigit(at)) { throw new IllegalArgumentException("Character " + at + " in position " + (i + 1) + " not valid"); } } return result; } public static String generateCode() { char[] cs = new char[10]; for (int i = 0; i < cs.length; i++) { cs[i] = ALPHABET.charAt(RANDOM.nextInt(ALPHABET.length())); } return new String(cs); } public static Coupon parseArguments(String[] args) { Map<String, String> kv = new HashMap<>(); String k = null; for (String arg : args) { if (k == null) { k = arg; } else { kv.put(k, arg); k = null; } } Coupon.CouponBuilder builder = Coupon.builder() .code(generateCode()) .effective(new Coupon.Effective("cart", ImmutableList.<Integer>of(), ImmutableList.<Integer>of())) .basketType("both") .startDate(new Date()); // Percentage / value discount String percentageStr = kv.get("percentage"); String valueStr = kv.get("value"); // One must be present, but not both. if (percentageStr == null && valueStr == null) { throw new IllegalArgumentException("percentage or value discount not found"); } if (percentageStr != null && valueStr != null) { throw new IllegalArgumentException("percentage and value discounts are mutually exclusive"); } if (percentageStr != null) { try { builder.discount(new Coupon.Discount("percentage", new BigDecimal(percentageStr), BigDecimal.ZERO)); } catch (NumberFormatException e) { throw new IllegalArgumentException("percentage is not valid (must be a number)"); } } else { try { builder.discount(new Coupon.Discount("value", BigDecimal.ZERO, new BigDecimal(valueStr))); } catch (NumberFormatException e) { throw new IllegalArgumentException("value is not valid (must be a number)"); } } // Expiry: none, limit of uses or expiry, String expiresStr = kv.get("expires"); String limitStr = kv.get("limit"); if (expiresStr != null && limitStr != null) { throw new IllegalArgumentException("expires and limit are mutually exclusive"); } if (expiresStr != null) { long ms = parseDuration(expiresStr); if (ms == 0) { throw new IllegalArgumentException("Invalid duration!"); } builder.expire(new Coupon.Expire("timestamp", 0, new Date(System.currentTimeMillis() + ms))); } else if (limitStr != null) { try { builder.expire(new Coupon.Expire("limit", Integer.parseInt(limitStr), new Date())); } catch (NumberFormatException e) { throw new IllegalArgumentException("limit is not valid (must be a number)"); } } else { builder.expire(new Coupon.Expire("never", 0, new Date())); } String minimumBasket = kv.get("min_value"); if (minimumBasket != null) { try { builder.minimum(new BigDecimal(minimumBasket)); } catch (NumberFormatException e) { throw new IllegalArgumentException("min_value is not valid (must be a number)"); } } else { builder.minimum(BigDecimal.ZERO); } String perUserUses = kv.get("user_limit"); if (perUserUses != null) { try { builder.userLimit(Integer.parseInt(perUserUses)); } catch (NumberFormatException e) { throw new IllegalArgumentException("user_limit is not valid (must be a number)"); } } return builder.build(); } }