/* FichothequeLib_API - Copyright (c) 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;

import java.text.ParseException;
import net.fichotheque.Fichotheque;
import net.fichotheque.FichothequeQuestioner;
import net.fichotheque.Subset;
import net.fichotheque.SubsetItem;
import net.fichotheque.SubsetKey;
import net.fichotheque.addenda.Addenda;
import net.fichotheque.addenda.Document;
import net.fichotheque.addenda.Version;
import net.fichotheque.sphere.LoginKey;
import net.fichotheque.sphere.Redacteur;
import net.fichotheque.sphere.Sphere;
import net.fichotheque.sphere.UserLoginException;
import net.fichotheque.thesaurus.Motcle;
import net.fichotheque.thesaurus.Thesaurus;
import net.mapeadores.util.annotation.Nullable;


/**
 *
 * @author Vincent Calame
 */
public class DefaultFichothequeQuestioner implements FichothequeQuestioner {

    private final Fichotheque fichotheque;

    public DefaultFichothequeQuestioner(Fichotheque fichotheque) {
        this.fichotheque = fichotheque;
    }

    @Override
    public SubsetItem parseGlobalId(String globalId, short subsetCategory, @Nullable Subset defaultSubset) throws ParseException {
        int idx = globalId.indexOf('/');
        if (idx == 0) {
            if (globalId.length() == 1) {
                throw new ParseException(globalId, 0);
            }
            idx = -1;
            globalId = globalId.substring(1);
        }
        Subset subset;
        int id;
        if (idx == -1) {
            if (defaultSubset == null) {
                throw new ParseException(globalId, 0);
            }
            subset = defaultSubset;
            try {
                id = Integer.parseInt(globalId);
            } catch (NumberFormatException nfe) {
                throw new ParseException(globalId, 0);
            }
        } else {
            if (idx == globalId.length() - 1) {
                throw new ParseException(globalId, 0);
            }
            String subsetName = globalId.substring(0, idx);
            SubsetKey subsetKey = SubsetKey.parse(subsetCategory, subsetName);
            subset = fichotheque.getSubset(subsetKey);
            if (subset == null) {
                throw new ParseException(globalId, 0);
            }
            try {
                id = Integer.parseInt(globalId.substring(idx + 1));

            } catch (NumberFormatException nfe) {
                throw new ParseException(globalId, idx);
            }
        }
        if (id < 0) {
            throw new ParseException(globalId, 0);
        }
        SubsetItem subsetItem = subset.getSubsetItemById(id);
        if (subsetItem == null) {
            throw new ParseException(globalId, 0);
        }
        return subsetItem;
    }

    @Override
    public Redacteur getRedacteurByLogin(String key, @Nullable SubsetKey defaultSphereKey) throws UserLoginException {
        try {
            LoginKey loginKey = LoginKey.parse(key);
            Sphere sphere = (Sphere) fichotheque.getSubset(loginKey.getSphereKey());
            if (sphere == null) {
                throw new UserLoginException(UserLoginException.UNKNOWN_SPHERE);
            }
            Redacteur redacteur = sphere.getRedacteurByLogin(loginKey.getLogin());
            if (redacteur == null) {
                throw new UserLoginException(UserLoginException.UNKNOWN_LOGIN);
            }
            return redacteur;
        } catch (ParseException pe) {

        }
        int idx = key.indexOf('/');
        if (idx != -1) {
            Redacteur redacteur = getRedacteurByGlobalId(key);
            if (redacteur != null) {
                return redacteur;
            } else {
                throw new UserLoginException(UserLoginException.MALFORMED_KEY);
            }
        }
        if (defaultSphereKey == null) {
            throw new UserLoginException(UserLoginException.MALFORMED_KEY);
        } else {
            Sphere defaultSphere = (Sphere) fichotheque.getSubset(defaultSphereKey);
            if (defaultSphere == null) {
                throw new UserLoginException(UserLoginException.UNKNOWN_SPHERE);
            } else {
                Redacteur redacteur = defaultSphere.getRedacteurByLogin(key);
                if (redacteur == null) {
                    throw new UserLoginException(UserLoginException.UNKNOWN_LOGIN);
                }
                return redacteur;
            }
        }
    }

    @Override
    public Motcle parseGlobalIdalpha(String globalIdalpha) throws ParseException {
        int idx = globalIdalpha.indexOf('!');
        if (idx == -1) {
            throw new ParseException(globalIdalpha, 0);
        }
        String subsetName = globalIdalpha.substring(0, idx);
        SubsetKey subsetKey = SubsetKey.parse(SubsetKey.CATEGORY_THESAURUS, subsetName);
        Thesaurus thesaurus = (Thesaurus) fichotheque.getSubset(subsetKey);
        if (thesaurus == null) {
            throw new ParseException(globalIdalpha, 0);
        }
        Motcle motcle = thesaurus.getMotcleByIdalpha(globalIdalpha.substring(idx + 1));
        if (motcle == null) {
            throw new ParseException(globalIdalpha, 0);
        }
        return motcle;
    }

    @Override
    public Version parseVersionKey(String versionKey) throws ParseException {
        int idx = versionKey.indexOf('/');
        if (idx == -1) {
            throw new ParseException("mising / character: " + versionKey, 0);
        }
        SubsetKey addendaKey = SubsetKey.parse(SubsetKey.CATEGORY_ADDENDA, versionKey.substring(0, idx));
        Addenda addenda = (Addenda) fichotheque.getSubset(addendaKey);
        if (addenda == null) {
            throw new ParseException("unknown addenda: " + versionKey, 0);
        }
        int idx2 = versionKey.indexOf('.');
        if (idx2 == -1) {
            throw new ParseException("mising . character: " + versionKey, idx + 1);
        }
        int documentid;
        try {
            documentid = Integer.parseInt(versionKey.substring(idx + 1, idx2));
        } catch (NumberFormatException nfe) {
            throw new ParseException("documentid not integer: " + versionKey, idx + 1);
        }
        Document document = addenda.getDocumentById(documentid);
        if (document == null) {
            throw new ParseException("unknwon documentid: " + versionKey, idx + 1);
        }
        Version version = document.getVersionByExtension(versionKey.substring(idx2 + 1));
        if (version == null) {
            throw new ParseException("unknwon extension: " + versionKey, idx2 + 1);
        }
        return version;
    }


}
