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

/*
 * Copyright 2022 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.List;

import de.duehl.basics.text.Text;
import de.duehl.basics.text.data.FoundSearch;

/**
 * Diese Klasse findet im Text (ent) den längsten der bekannten Begriffe zur Einführung einer Art
 * (ein Intro wie z.B. "E-Mail:") und sucht dann dahinter eine Ausprägung dieser Art und hält
 * diese, so gefunden, in einer Variablen vor.
 *
 * Dabei wird der gefundene Begriff in ent durch einen Platzhalter ersetzt und ein Kommentar zur
 * Auffindung des Begriffs gesammelt.
 *
 * @version 1.01     2022-05-06
 * @author Christian Dühl
 */

public class SingleEntityReplacerViaIntroList extends SingleEntityReplacer {

    /** Liste mit den Einleitungen zum gesuchten Begriff ("E-Mail:"). */
    private final List<String> beginnings;

    /**
     * Objekt das ermittelt, ob der übergebene String mit einer Ausprägung des gewünschten Begriffs
     * beginnt. Tut er das nicht, wird der leere String zurückgegeben, anderenfalls der erkannte
     * Wert.
     */
    private final ThingAtStartDeterminer thingAtStartDeterminer;

    /**
     * Wird zum Kommentare zur automatischen Vergabe hinzugefügt, wenn ein Begriff dieser Art
     * gefunden wird.
     */
    private final String additionalAutoComment;

    /**
     * Konstruktor.
     *
     * @param ent
     *            Ursprünglich der rohe Text, dieser wird/wurde bei der Analyse aber verändert und
     *            Teile durch die Entitäten wie <<street>> ersetzt.
     * @param beginnings
     *            Liste mit den Begriffen.
     * @param placeholder
     *            Der Platzhalter in der Form <<street>>, durch den der gefundene Begriff ersetzt
     *            wird.
     * @param additionalAutoComment
     *            Wird zum Kommentare zur automatischen Vergabe hinzugefügt, wenn ein Begriff
     *            dieser Art gefunden wird.
     * @param thingAtStartDeterminer
     *            Objekt das ermittelt, ob der übergebene String mit einer Ausprägung des
     *            gewünschten Begriffs beginnt. Tut er das nicht, wird der leere String
     *            zurückgegeben, anderenfalls der erkannte Wert.
     */
    public SingleEntityReplacerViaIntroList(String ent, List<String> beginnings, String placeholder,
            String additionalAutoComment, ThingAtStartDeterminer thingAtStartDeterminer) {
        super(ent, placeholder);
        this.beginnings = beginnings;
        this.thingAtStartDeterminer = thingAtStartDeterminer;
        this.additionalAutoComment = additionalAutoComment;
    }

    /** Sucht, merkt und ersetzt in ent. */
    @Override
    public void replace() {
        replaceViaListAndThingsAtStartDeterminer();
    }

    /** Sucht über die Intro-Liste und wird standardmäßig aufgerufen. */
    protected final void replaceViaListAndThingsAtStartDeterminer() {
        FoundSearch foundSearch = Text.findLongest(ent, beginnings);
        if (foundSearch.wasSuccessfull()) {
            int startIndex = foundSearch.getIndex();
            String before = ent.substring(0, startIndex);

            int endIndex = foundSearch.getEnd();
            String after = ent.substring(endIndex);
            while (after.startsWith(" ") || after.startsWith(":")) {
                after = after.substring(1);
            }

            String pureValue = thingAtStartDeterminer.determineThingAtStart(after);
            if (!pureValue.isEmpty()) {
                value = pureValue;
                after = after.substring(pureValue.length());
                ent = before + placeholder + after;
                appendAutoComment(additionalAutoComment);
            }
        }
    }

    /**
     * Sucht den Begriff direkt im Text, wird standardmäßig NICHT aufgerufen.
     *
     * Will man die Methode nutzen, so muss man replace() überschreiben.
     */
    protected final void replaceWithoutIntro(String additionalAutoCommentWithoutIntro,
            DetectSingleThingFinder thingFinder) {
        FoundSearch foundSearch = thingFinder.findThing(ent);
        if (foundSearch.wasSuccessfull()) {
            int startIndex = foundSearch.getIndex();
            String before = ent.substring(0, startIndex);
            int endIndex = foundSearch.getEnd();
            String after = ent.substring(endIndex);
            value = foundSearch.getSearch();
            ent = before + placeholder + after;
            appendAutoComment(additionalAutoCommentWithoutIntro);
        }
    }

}
