package nl.hsac.fitnesse.symbols;

import fitnesse.wikitext.parser.*;
import nl.hsac.fitnesse.util.RandomUtil;

import java.util.HashMap;
import java.util.Map;

/**
 * Generates random Dutch license plates.
 * Usage: !randomDutchLicensePlate (Category) (Sidecode)
 * Sidecodes 4-10 are supported (see: https://nl.wikipedia.org/wiki/Nederlands_kenteken)
 * Sidecode 7 is used by default.
 * Category expects a single letter that is used as the first letter in the license plate
 * (f.e. D for mopeds, M for Motorcycle, V for light company cars, B for heavy company cars (>3500KG))
 */
public class RandomDutchLicensePlate extends SymbolBase implements Rule, Translation {

    private static final RandomUtil RANDOM_UTIL = new RandomUtil();
    private static final String CATEGORY = "Category";
    private static final String SIDECODE = "Sidecode";

    public RandomDutchLicensePlate() {
        super("RandomDutchLicensePlate");
        wikiMatcher(new Matcher().string("!randomDutchLicensePlate"));
        wikiRule(this);
        htmlTranslation(this);
    }

    public Maybe<Symbol> parse(Symbol current, Parser parser) {
        Maybe<Symbol> result = storeParenthesisContent(current, parser, CATEGORY);
        if (!result.isNothing()) {
            result = storeParenthesisContent(current, parser, SIDECODE);
        }
        return result;
    }

    public String toTarget(Translator translator, Symbol symbol) {
        String category = symbol.getProperty(CATEGORY, "");
        String sideCode = symbol.getProperty(SIDECODE, "7");
        return randomLicensePlate(sideCode, category.toUpperCase());
    }

    private String randomLicensePlate(String sideCode, String category) {

        int sideCodeToUse = Integer.parseInt(sideCode);
        if (sideCodeToUse < 4 || sideCodeToUse > 10) {
            throw new IllegalArgumentException("Only sidecodes 4 to 10 are supported!");
        }
        String pattern = sidecodePatterns().get(sideCodeToUse);
        String permitted = "BDFGHJKLMNPRSTVXZ";

        if (category.length() == 1) {
            pattern = pattern.replaceFirst("@", category);
        }
        while (pattern.contains("@")) {
            pattern = pattern.replaceFirst("@", RANDOM_UTIL.randomString(permitted, 1));
        }
        while (pattern.contains("#")) {
            pattern = pattern.replaceFirst("#", RANDOM_UTIL.randomString("1234567890", 1));
        }
        return pattern;

    }

    private Map<Integer, String> sidecodePatterns() {
        Map<Integer, String> patterns = new HashMap<>();
        patterns.put(4, "##-@@-##"); //SideCode 4
        patterns.put(5, "@@-@@-##"); //SideCode 5
        patterns.put(6, "##-@@-@@"); //SideCode 6
        patterns.put(7, "##-@@@-#"); //SideCode 7
        patterns.put(8, "#-@@@-##");  //SideCode 8
        patterns.put(9, "@@-###-@");  //SideCode 9
        patterns.put(10, "@-###-@@"); //SideCode 10
        return patterns;
    }

}

@@ -1778,33 +1778,12 @@
 Use 
-%3C 4 %7C%7C sideCodeToUse 
 %3E 1
-0
+4
 ) %7B%0A
@@ -1834,14 +1834,9 @@
 on(%22
-Only s
+S
 idec
@@ -1844,20 +1844,19 @@
 des 
-4 to 10
+%3E 14
  are 
+un
 supp
@@ -2515,24 +2515,25 @@
 ashMap%3C%3E();%0A
+%0A
         patt
@@ -2545,20 +2545,170 @@
 put(
-4, %22##-@@-##
+1, %22@@-##-##%22); //SideCode 1%0A        patterns.put(2, %22##-##-XX%22); //SideCode 2%0A        patterns.put(3, %22##-@@-##%22); //SideCode 3%0A        patterns.put(4, %22@@-##-@@
 %22); 
@@ -2972,16 +2972,16 @@
 eCode 9%0A
-
         
@@ -3024,16 +3024,226 @@
 Code 10%0A
+        patterns.put(11, %22@@@-##-@%22); //SideCode 11%0A        patterns.put(12, %22@-##-@@@%22);  //SideCode 12%0A        patterns.put(13, %22#-@@-###%22);  //SideCode 13%0A        patterns.put(14, %22###-@@-#%22); //SideCode 14%0A
         

Support all sidecode formats