/* FichothequeLib_Tools - Copyright (c) 2006-2025 Vincent Calame - Exemole
 * Logiciel libre donné sous triple licence :
 * 1) selon les termes de la CeCILL V2
 * 2) selon les termes de l’EUPL V.1.1
 * 3) selon les termes de la GNU GPLv3
 * Voir le fichier licences.txt
 */


package net.fichotheque.tools.parsers.junction;

import java.text.ParseException;
import net.mapeadores.util.text.StringUtils;


/**
 *
 * @author Vincent Calame
 */
public class TieToken {

    private final String text;
    private final String mode;
    private final int weight;

    private TieToken(String text, String mode, int weight) {
        this.text = text;
        this.mode = mode;
        this.weight = weight;
    }

    public String getMode() {
        return mode;
    }

    public int getWeight() {
        return weight;
    }

    public String getText() {
        return text;
    }


    /**
     * On suppose s nettoyé avant (trim() et s non vide et non nul).
     */
    public static TieToken parse(String s) {
        char lastChar = s.charAt(s.length() - 1);
        if (lastChar == '+') {
            return parsePlusStyle(s);
        } else if (lastChar == '>') {
            return parseCompleteStyle(s);
        } else if ((lastChar >= '0') && (lastChar <= '9')) {
            return parseNumberStyle(s);
        } else {
            return new TieToken(s, "", 1);
        }
    }

    private static TieToken parseNumberStyle(String s) {
        int dizaine = 1;
        int weight = 0;
        int idx = 0;
        for (int i = (s.length() - 1); i >= 0; i--) {
            char c = s.charAt(i);
            if ((c >= '0') && (c <= '9')) {
                if (i == 1) {
                    return new TieToken(s, "", 1);
                }
                int p = c - 48;
                weight = weight + p * dizaine;
                dizaine = dizaine * 10;
            } else {
                idx = i;
                break;
            }
        }
        for (int i = idx; i >= 1; i--) {
            char c = s.charAt(i);
            if (c == ' ') {
                continue;
            } else if (c == '+') {
                return new TieToken(s.substring(0, i).trim(), "", weight + 1);
            } else if (c == '<') {
                return new TieToken(s.substring(0, i).trim(), "", weight);
            } else {
                break;
            }
        }
        return new TieToken(s, "", 1);
    }

    private static TieToken parsePlusStyle(String s) {
        int p = 1;
        int lastIdx = s.length() - 1;
        for (int i = (lastIdx - 1); i >= 0; i--) {
            if (s.charAt(i) == '+') {
                p++;
                lastIdx--;
            } else {
                break;
            }
        }
        return new TieToken(s.substring(0, lastIdx).trim(), "", p + 1);
    }

    private static TieToken parseCompleteStyle(String s) {
        int idx = s.lastIndexOf('<');
        if (idx == -1) {
            return new TieToken(s, "", 1);
        }
        String info = s.substring(idx + 1, s.length() - 1).trim();
        String text = s.substring(0, idx).trim();
        int sepIdx = info.indexOf('_');
        if (sepIdx < 0) {
            try {
                int weight = Integer.parseInt(info);
                if (weight < 1) {
                    weight = 1;
                }
                return new TieToken(text, "", weight);
            } catch (NumberFormatException nfe) {
                try {
                    StringUtils.checkTechnicalName(info, false);
                    return new TieToken(text, info, 1);
                } catch (ParseException pe) {
                    return new TieToken(s, "", 1);
                }
            }
        } else {
            try {
                int weight = Integer.parseInt(info.substring(sepIdx + 1));
                if (weight < 1) {
                    weight = 1;
                }
                String mode = info.substring(0, sepIdx);
                StringUtils.checkTechnicalName(mode, false);
                return new TieToken(text, mode, weight);
            } catch (NumberFormatException | ParseException e) {
                return new TieToken(s, "", 1);
            }

        }
    }

}
