package de.duehl.basics.autodetect.ent.multiple;

/*
 * 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 de.duehl.basics.text.Text;
import de.duehl.basics.text.data.FoundSearch;

/**
 * Diese Klasse findet im Text (ent) alle bekannten Begriffe einer Art und sammelt diese in einer
 * Liste. Dabei werden die Begriffe in ent durch Platzhalter der Form <<function>> (ohne ":17"
 * darin) ersetzt.
 *
 * @version 1.01     2023-08-10
 * @author Christian Dühl
 */

public class MultipleEntityReplacerWithoutNumbersReplacer {

    /**
     * Ursprünglich der rohe Text, dieser wird/wurde bei der Analyse aber verändert und Teile durch
     * die Entitäten wie <<street>> ersetzt.
     */
    private String ent;

    /** Der Entitätenplatzhalter, z.B. <<befugnis>>. */
    private final String replacement;

    /** Klasse, die Begriffe in ent finden kann, ohne dies zu verändern. */
    private final DetectMultipleThingsFinder thingsFinder;

    /** Die Liste mit den gefundenen Entitäten. */
    private final List<String> valueList;

    /**
     * Konstruktor.
     *
     * @param ent
     *            Ursprünglich der rohe Text, dieser wird/wurde bei der Analyse aber verändert und
     *            Teile durch die Entitäten wie <<befugnis>> ersetzt.
     * @param replacement
     *            Der Entitätenplatzhalter, z.B. <<befugnis>>.
     * @param thingsFinder
     *            Klasse, die Begriffe in ent finden kann, ohne dies zu verändern.
     */
    public MultipleEntityReplacerWithoutNumbersReplacer(String ent, String replacement,
            DetectMultipleThingsFinder thingsFinder) {
        this.ent = ent;
        this.replacement = replacement;
        this.thingsFinder = thingsFinder;

        valueList = new ArrayList<>();
    }

    /** Sucht, sammelt und ersetzt in ent. */
    public void replace() {
        /* Bestimmt die Liste aller erkannten Begriffe in der Reihenfolge des Vorkommens in ent: */
        List<FoundSearch> foundSearches = thingsFinder.findAllThings(ent);

        /* Wir machen das rückwärts, denn anderenfalls müsste man die Indices alle umrechnen: */
        Collections.reverse(foundSearches);

        replaceFoundSearchesInEnt(foundSearches);

        /* Nun drehen wir die befüllte Liste wieder richtigherum: */
        Collections.reverse(valueList);
    }

    private void replaceFoundSearchesInEnt(List<FoundSearch> foundSearches) {
        List<FoundSearch> foundSearchesWeWantToReplace = new ArrayList<>();
        for (FoundSearch foundSearch : foundSearches) {
            int end = foundSearch.getEnd();
            String after = ent.substring(end);
            if (!Text.startsWithLowercaseLetter(after)) { // sonst haben wir nur den Anfang eines Wortes
                foundSearchesWeWantToReplace.add(foundSearch);
            }
        }

        for (FoundSearch foundSearch : foundSearchesWeWantToReplace) {
            String search = foundSearch.getSearch();
            int start = foundSearch.getIndex();
            int end = foundSearch.getEnd();
            String before = ent.substring(0, start);
            String after = ent.substring(end);

            valueList.add(search);
            ent = before + replacement + after;
        }
    }

    /**
     * Getter für den veränderten Text, in diesem wurden bei der Analyse Teile durch die Entitäten
     * wie <<befugnis>> ersetzt.
     */
    public final String getEnt() {
        return ent;
    }

    /** Getter für die Liste mit den gefundenen Entitäten. */
    public List<String> getValueList() {
        return valueList;
    }

}
