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

import java.text.ParseException;
import java.util.AbstractList;
import java.util.List;
import java.util.RandomAccess;
import net.fichotheque.SubsetKey;
import net.fichotheque.corpus.Corpus;
import net.fichotheque.corpus.FicheMeta;
import net.fichotheque.corpus.fiche.FicheAPI;
import net.fichotheque.corpus.fiche.FicheItem;
import net.fichotheque.corpus.fiche.FicheItems;
import net.fichotheque.corpus.fiche.PersonItem;
import net.fichotheque.corpus.metadata.CorpusField;
import net.fichotheque.corpus.metadata.FieldKey;
import net.fichotheque.sphere.LoginKey;
import net.fichotheque.sphere.Redacteur;


/**
 *
 * @author Vincent Calame
 */
public final class SphereUtils {

    private SphereUtils() {
    }

    /**
     * Un identifiant de connexion (login) doit répondre à l'expression
     * rationnelle : [a-zA-Z][a-zA-Z0-9]*.
     */
    public static boolean testLogin(String login) {
        try {
            LoginKey.checkLogin(login);
            return true;
        } catch (ParseException pe) {
            return false;
        }
    }

    public static boolean testRedacteurs(Corpus corpus, Redacteur redacteur) {
        String globalId = redacteur.getGlobalId();
        for (FicheMeta ficheMeta : corpus.getFicheMetaList()) {
            if (ficheMeta.belongsTo(globalId)) {
                return true;
            }
        }
        return false;
    }

    public static boolean testRedacteursAndFields(Corpus corpus, Redacteur redacteur, List<CorpusField> personneFieldList) {
        boolean redacTest = testRedacteurs(corpus, redacteur);
        if (redacTest) {
            return true;
        } else if (personneFieldList.isEmpty()) {
            return false;
        }
        FieldKey[] fieldKeyArray = CorpusMetadataUtils.toFieldKeyArray(personneFieldList);
        for (FicheMeta ficheMeta : corpus.getFicheMetaList()) {
            FicheAPI fiche = corpus.getFicheAPI(ficheMeta, false);
            for (FieldKey fieldKey : fieldKeyArray) {
                Object value = fiche.getValue(fieldKey);
                if (value != null) {
                    switch (fieldKey.getCategory()) {
                        case FieldKey.PROP_CATEGORY: {
                            boolean here = testFicheItem(redacteur, (FicheItem) value);
                            if (here) {
                                return true;
                            }
                            break;
                        }
                        case FieldKey.INFO_CATEGORY: {
                            for (FicheItem ficheItem : (FicheItems) value) {
                                boolean here = testFicheItem(redacteur, ficheItem);
                                if (here) {
                                    return true;
                                }
                            }
                            break;
                        }
                    }
                }
            }
        }
        return false;
    }


    public static boolean testFicheItem(Redacteur redacteur, FicheItem ficheItem) {
        if (!(ficheItem instanceof PersonItem)) {
            return false;
        }
        String redacteurGlobalId = ((PersonItem) ficheItem).getRedacteurGlobalId();
        if (redacteurGlobalId != null) {
            return redacteurGlobalId.equals(redacteur.getGlobalId());
        } else {
            return false;
        }
    }

    public static boolean testGlobalId(String userGlobalId) {
        try {
            getSubsetKey(userGlobalId);
            getId(userGlobalId);
            return true;
        } catch (ParseException pe) {
            return false;
        }
    }

    public static SubsetKey getSubsetKey(String userGlobalId) throws ParseException {
        int idx = userGlobalId.indexOf('/');
        if (idx == -1) {
            throw new ParseException("Missing /", 0);
        }
        return SubsetKey.parse(SubsetKey.CATEGORY_SPHERE, userGlobalId.substring(0, idx));
    }

    public static int getId(String userGlobalId) throws ParseException {
        int idx = userGlobalId.indexOf('/');
        if (idx == -1) {
            throw new ParseException("Missing /", 0);
        }
        try {
            int id = Integer.parseInt(userGlobalId.substring(idx + 1));
            if (idx < 1) {
                throw new ParseException("Not positive integer", idx);
            }
            return id;
        } catch (NumberFormatException nfe) {
            throw new ParseException("Not integer", idx);
        }
    }

    public static List<Redacteur> wrap(Redacteur[] array) {
        return new RedacteurList(array);
    }


    private static class RedacteurList extends AbstractList<Redacteur> implements RandomAccess {

        private final Redacteur[] array;

        private RedacteurList(Redacteur[] array) {
            this.array = array;
        }

        @Override
        public int size() {
            return array.length;
        }

        @Override
        public Redacteur get(int index) {
            return array[index];
        }

    }

}
