package de.duehl.basics.autodetect.tools;

/*
 * Copyright 2023 Christian Dühl. All rights reserved.
 *
 * This program is free software. You can redistribute it and/or
 * modify it under the same terms as perl:
 *
 * general:  http://dev.perl.org/licenses/
 * GPL:      http://dev.perl.org/licenses/gpl1.html
 * artistic: http://dev.perl.org/licenses/artistic.html
 */

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import de.duehl.basics.replacements.ReplacementHelper;
import de.duehl.basics.text.NumberString;

/**
 * Diese Klasse hält Hilfsmethoden rund um Entitäten bereit.
 *
 * @version 1.01     2023-03-09
 * @author Christian Dühl
 */

public class EntityHelper {

    /**
     * Nachdem eine Entität gelöscht wurde, müssen alle höheren Indices in ent um eins reduziert
     * werden. Das wird hier gemacht.
     *
     * @param ent
     *            String mit Entitäten der Form '<<street:1>>'.
     * @param entityRegex
     *            Regulärer Ausdruck, welcher auf die zu verändernden Entitäten passt.
     *            Dieser hat die Form "<<" + replacementFrontPart + ":(\\d+)>>".
     * @param startingPosition
     *            Position (1-basiert) ab dem die Position um eins zu reduzieren ist. Bei de
     *            Startposition 3 wird also <<street:3>> und <<street:4>> verändert, nicht aber
     *            <<street:1>> und <<street:2>>, wobei letztere vorher aus ent entfernt worden sein
     *            sollte.
     * @return Korrigierter EntitätenString
     */
    public static String repairHigherPositions(String ent, String entityRegex, int startingPosition) {
        List<Integer> positions = new ArrayList<>();

        Pattern pattern = Pattern.compile(entityRegex);
        Matcher matcher = pattern.matcher(ent);
        while (matcher.find()) {
            String positionString = matcher.group(1);
            int position = NumberString.parseInt(positionString);
            if (position >= startingPosition) {
                positions.add(position);
            }
        }

        Collections.sort(positions); // wenn sie durcheinander sind, werden manche mehrfach ersetzt

        String replacementFrontPart = extractReplacementFrontPartFromEntityRegex(entityRegex);

        String entOut = ent;
        for (int index = 0; index < positions.size(); ++index) {
            int position = positions.get(index);
            int correctedPosition = position - 1;

            String toReplace = "<<" + replacementFrontPart + ":" + position + ">>";
            String replacement = "<<" + replacementFrontPart + ":" + correctedPosition + ">>";

            entOut = entOut.replace(toReplace, replacement);
        }

        return entOut;
    }

    /**
     * Ermittelt aus dem übergebenen regulären Ausdruck, welcher auf die zu verändernden Entitäten
     * passt, den Teil vorn.
     *
     * @param entityRegex
     *            Regulärer Ausdruck, welcher auf die zu verändernden Entitäten passt. Dieser hat
     *            die Form "<<" + replacementFrontPart + ":(\\d+)>>".
     */
    public static String extractReplacementFrontPartFromEntityRegex(String entityRegex) {
        return ReplacementHelper.determinePlaceholderFrontPart(entityRegex);
    }

}
