/* FichothequeLib_API - Copyright (c) 2019-2021 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.util.AbstractList;
import java.util.Collections;
import java.util.List;
import java.util.RandomAccess;
import net.fichotheque.exportation.transformation.TemplateContentDescription;
import net.fichotheque.exportation.transformation.TemplateDef;
import net.fichotheque.exportation.transformation.TemplateDescription;
import net.fichotheque.exportation.transformation.TemplateKey;
import net.fichotheque.exportation.transformation.TransformationDescription;
import net.fichotheque.exportation.transformation.TransformationKey;
import net.fichotheque.namespaces.TransformationSpace;
import net.mapeadores.util.attr.Attribute;
import net.mapeadores.util.attr.Attributes;
import net.mapeadores.util.text.Labels;
import net.mapeadores.util.text.StringUtils;


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

    public final static List<TemplateDescription> EMPTY_TEMPLATEDESCRIPTIONLIST = Collections.emptyList();

    private TransformationUtils() {

    }

    public static boolean isUseableTemplateState(String state) {
        switch (state) {
            case TemplateDescription.OK_STATE:
            case TemplateDescription.WITH_WARNINGS_STATE:
                return true;
            default:
                return false;
        }
    }

    public static TransformationDescription getEmptyTransformationDescription(TransformationKey transformationKey) {
        return new EmptyTransformationDescription(transformationKey);
    }

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

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

    public static int getExtractVersion(Attributes attributes) {
        String text = null;
        Attribute attribute = attributes.getAttribute(TransformationSpace.EXTRACTVERSION_KEY);
        if (attribute != null) {
            text = attribute.getFirstValue();
        }
        return ExtractionUtils.parseExtractVersion(text);
    }

    public static boolean isWithEmptyComponents(Attributes attributes, boolean defaultValue) {
        Attribute attribute = attributes.getAttribute(TransformationSpace.EMPTYCOMPONENTS_KEY);
        if (attribute == null) {
            return defaultValue;
        }
        return StringUtils.toBoolean(attribute.getFirstValue(), defaultValue);
    }

    public static TemplateDef deriveTemplateDef(TemplateDef originalTemplateDef, TemplateKey newTemplateKey) {
        return new DerivedTemplateDef(originalTemplateDef, newTemplateKey);
    }


    private static class EmptyTransformationDescription implements TransformationDescription {

        private final TransformationKey transformationKey;

        private EmptyTransformationDescription(TransformationKey transformationKey) {
            this.transformationKey = transformationKey;
        }

        @Override
        public TransformationKey getTransformationKey() {
            return transformationKey;
        }

        @Override
        public List<TemplateDescription> getSimpleTemplateDescriptionList() {
            return EMPTY_TEMPLATEDESCRIPTIONLIST;
        }

        @Override
        public List<TemplateDescription> getStreamTemplateDescriptionList() {
            return EMPTY_TEMPLATEDESCRIPTIONLIST;
        }

    }


    private static class TemplateDescriptionList extends AbstractList<TemplateDescription> implements RandomAccess {

        private final TemplateDescription[] array;

        private TemplateDescriptionList(TemplateDescription[] array) {
            this.array = array;
        }

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

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

    }


    private static class TemplateContentList extends AbstractList<TemplateContentDescription> implements RandomAccess {

        private final TemplateContentDescription[] array;

        private TemplateContentList(TemplateContentDescription[] array) {
            this.array = array;
        }

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

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

    }


    private static class DerivedTemplateDef implements TemplateDef {

        private final TemplateKey templateKey;
        private final TemplateDef originalTemplateDef;

        private DerivedTemplateDef(TemplateDef originalTemplateDef, TemplateKey templateKey) {
            this.templateKey = templateKey;
            this.originalTemplateDef = originalTemplateDef;
        }

        @Override
        public TemplateKey getTemplateKey() {
            return templateKey;
        }

        @Override
        public Labels getTitleLabels() {
            return originalTemplateDef.getTitleLabels();
        }

        @Override
        public Attributes getAttributes() {
            return originalTemplateDef.getAttributes();
        }

    }

}
