/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.myfaces.extensions.validator.beanval.util;

import org.apache.myfaces.extensions.validator.beanval.ExtValBeanValidationContext;
import org.apache.myfaces.extensions.validator.beanval.payload.ViolationSeverity;
import org.apache.myfaces.extensions.validator.beanval.annotation.BeanValidation;
import org.apache.myfaces.extensions.validator.beanval.annotation.ModelValidation;
import org.apache.myfaces.extensions.validator.beanval.annotation.extractor.DefaultGroupControllerScanningExtractor;
import org.apache.myfaces.extensions.validator.beanval.storage.ModelValidationEntry;
import org.apache.myfaces.extensions.validator.core.el.ELHelper;
import org.apache.myfaces.extensions.validator.core.el.ValueBindingExpression;
import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;
import org.apache.myfaces.extensions.validator.core.property.PropertyDetails;
import org.apache.myfaces.extensions.validator.core.property.PropertyInformation;
import org.apache.myfaces.extensions.validator.core.validation.message.FacesMessageHolder;
import org.apache.myfaces.extensions.validator.internal.UsageCategory;
import org.apache.myfaces.extensions.validator.internal.UsageInformation;
import org.apache.myfaces.extensions.validator.internal.ToDo;
import org.apache.myfaces.extensions.validator.internal.Priority;
import org.apache.myfaces.extensions.validator.util.ExtValUtils;
import org.apache.myfaces.extensions.validator.util.ReflectionUtils;
import org.apache.myfaces.extensions.validator.util.ProxyUtils;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.ValidatorException;
import javax.validation.ConstraintViolation;
import javax.validation.Payload;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Logger;

/**
 * @since x.x.3
 */
@UsageInformation(UsageCategory.INTERNAL)
class ExtValBeanValidationMetaDataInternals
{
    private Logger logger;
    private LabeledMessageInternals labeledMessageInternals = new LabeledMessageInternals();
    private ELHelper elHelper;

    ExtValBeanValidationMetaDataInternals(Logger logger, ELHelper elHelper)
    {
        this.logger = logger;
        this.elHelper = elHelper;
    }

    void extractExtValBeanValidationMetaData(PropertyDetails propertyDetails,
                                             boolean processModelValidation,
                                             String[] key,
                                             Object firstBean,
                                             List<Class> foundGroupsForPropertyValidation,
                                             List<Class> restrictedGroupsForPropertyValidation,
                                             List<ModelValidationEntry> modelValidationEntryList,
                                             List<Class> restrictedGroupsForModelValidation,
                                             String activeViewId)
    {
        inspectFirstBean(processModelValidation,
                firstBean,
                foundGroupsForPropertyValidation,
                restrictedGroupsForPropertyValidation,
                modelValidationEntryList,
                restrictedGroupsForModelValidation,
                activeViewId);

        inspectFirstProperty(processModelValidation,
                key,
                firstBean,
                foundGroupsForPropertyValidation,
                restrictedGroupsForPropertyValidation,
                modelValidationEntryList,
                restrictedGroupsForModelValidation,
                activeViewId,
                key.length == 2);

        inspectBaseOfProperty(propertyDetails,
                processModelValidation,
                foundGroupsForPropertyValidation,
                restrictedGroupsForPropertyValidation,
                modelValidationEntryList,
                restrictedGroupsForModelValidation,
                activeViewId);

        inspectLastProperty(propertyDetails,
                processModelValidation,
                foundGroupsForPropertyValidation,
                restrictedGroupsForPropertyValidation,
                modelValidationEntryList,
                restrictedGroupsForModelValidation,
                activeViewId);
    }

    void processExtValBeanValidationMetaData(UIComponent component,
                                             PropertyDetails propertyDetails,
                                             List<Class> foundGroupsForPropertyValidation,
                                             List<Class> restrictedGroupsForPropertyValidation,
                                             List<ModelValidationEntry> modelValidationEntryList,
                                             List<Class> restrictedGroupsForModelValidation,
                                             String activeViewId)
    {
        ExtValBeanValidationContext extValBeanValidationContext = ExtValBeanValidationContext.getCurrentInstance();

        String clientId = component.getClientId(FacesContext.getCurrentInstance());

        processFoundGroups(extValBeanValidationContext, activeViewId, clientId,
                foundGroupsForPropertyValidation);

        processRestrictedGroups(extValBeanValidationContext, activeViewId, clientId,
                restrictedGroupsForPropertyValidation);

        initModelValidation(extValBeanValidationContext, component, propertyDetails,
                modelValidationEntryList, restrictedGroupsForModelValidation);
    }

    private void inspectFirstBean(boolean processModelValidation,
                                  Object firstBean,
                                  List<Class> foundGroupsForPropertyValidation,
                                  List<Class> restrictedGroupsForPropertyValidation,
                                  List<ModelValidationEntry> modelValidationEntryList,
                                  List<Class> restrictedGroupsForModelValidation,
                                  String activeViewId)
    {
        processClass(firstBean,
                foundGroupsForPropertyValidation,
                restrictedGroupsForPropertyValidation,
                modelValidationEntryList,
                restrictedGroupsForModelValidation,
                activeViewId,
                processModelValidation);
    }

    private void inspectFirstProperty(boolean processModelValidation,
                                      String[] key,
                                      Object firstBean,
                                      List<Class> foundGroupsForPropertyValidation,
                                      List<Class> restrictedGroupsForPropertyValidation,
                                      List<ModelValidationEntry> modelValidationEntryList,
                                      List<Class> restrictedGroupsForModelValidation,
                                      String activeViewId,
                                      boolean isLastProperty)
    {
        processFieldsAndProperties(key[0] + "." + key[1],
                firstBean,
                key[1],
                foundGroupsForPropertyValidation,
                restrictedGroupsForPropertyValidation,
                modelValidationEntryList,
                restrictedGroupsForModelValidation,
                activeViewId,
                processModelValidation,
                isLastProperty);
    }

    private void inspectBaseOfProperty(PropertyDetails propertyDetails,
                                       boolean processModelValidation,
                                       List<Class> foundGroupsForPropertyValidation,
                                       List<Class> restrictedGroupsForPropertyValidation,
                                       List<ModelValidationEntry> modelValidationEntryList,
                                       List<Class> restrictedGroupsForModelValidation,
                                       String activeViewId)
    {
        processClass(propertyDetails.getBaseObject(),
                foundGroupsForPropertyValidation,
                restrictedGroupsForPropertyValidation,
                modelValidationEntryList,
                restrictedGroupsForModelValidation,
                activeViewId,
                processModelValidation);
    }

    private void inspectLastProperty(PropertyDetails propertyDetails,
                                     boolean processModelValidation,
                                     List<Class> foundGroupsForPropertyValidation,
                                     List<Class> restrictedGroupsForPropertyValidation,
                                     List<ModelValidationEntry> modelValidationEntryList,
                                     List<Class> restrictedGroupsForModelValidation,
                                     String activeViewId)
    {
        processFieldsAndProperties(
                propertyDetails.getKey(),
                propertyDetails.getBaseObject(),
                propertyDetails.getProperty(),
                foundGroupsForPropertyValidation,
                restrictedGroupsForPropertyValidation,
                modelValidationEntryList,
                restrictedGroupsForModelValidation,
                activeViewId,
                processModelValidation,
                true);
    }

    private void processClass(Object objectToInspect,
                              List<Class> foundGroupsForPropertyValidation,
                              List<Class> restrictedGroupsForPropertyValidation,
                              List<ModelValidationEntry> modelValidationEntryList,
                              List<Class> restrictedGroupsForModelValidation,
                              String activeViewId,
                              boolean processModelValidation)
    {
        Class classToInspect = ProxyUtils.getUnproxiedClass(objectToInspect.getClass());

        while (!Object.class.getName().equals(classToInspect.getName()))
        {
            transferGroupValidationInformationToFoundGroups(
                    classToInspect,
                    objectToInspect,
                    foundGroupsForPropertyValidation,
                    restrictedGroupsForPropertyValidation,
                    modelValidationEntryList,
                    restrictedGroupsForModelValidation,
                    activeViewId,
                    processModelValidation);

            processInterfaces(classToInspect, objectToInspect,
                    foundGroupsForPropertyValidation,
                    restrictedGroupsForPropertyValidation,
                    modelValidationEntryList,
                    restrictedGroupsForModelValidation,
                    activeViewId,
                    processModelValidation);

            classToInspect = classToInspect.getSuperclass();
        }
    }

    private void processFieldsAndProperties(String key,
                                            Object base,
                                            String property,
                                            List<Class> foundGroupsForPropertyValidation,
                                            List<Class> restrictedGroupsForPropertyValidation,
                                            List<ModelValidationEntry> modelValidationEntryList,
                                            List<Class> restrictedGroupsForModelValidation,
                                            String activeViewId,
                                            boolean processModelValidation,
                                            boolean isLastProperty)
    {
        PropertyInformation propertyInformation = new DefaultGroupControllerScanningExtractor()
                .extract(FacesContext.getCurrentInstance(), new PropertyDetails(key, base, property));

        for (MetaDataEntry metaDataEntry : propertyInformation.getMetaDataEntries())
        {
            if (metaDataEntry.getValue() instanceof BeanValidation)
            {
                tryToProcessMetaData((BeanValidation) metaDataEntry.getValue(),
                        tryToCreateNewTarget(base, property, isLastProperty),
                        foundGroupsForPropertyValidation,
                        restrictedGroupsForPropertyValidation,
                        modelValidationEntryList,
                        restrictedGroupsForModelValidation,
                        activeViewId,
                        processModelValidation);
            }
            else if (metaDataEntry.getValue() instanceof BeanValidation.List)
            {
                for (BeanValidation currentBeanValidation : ((BeanValidation.List) metaDataEntry.getValue()).value())
                {
                    tryToProcessMetaData(currentBeanValidation,
                            tryToCreateNewTarget(base, property, isLastProperty),
                            foundGroupsForPropertyValidation,
                            restrictedGroupsForPropertyValidation,
                            modelValidationEntryList,
                            restrictedGroupsForModelValidation,
                            activeViewId,
                            processModelValidation);
                }
            }
        }
    }

    private Object tryToCreateNewTarget(Object base, String property, boolean isLastProperty)
    {
        if(isLastProperty)
        {
            return base;
        }

        Object result = getValueOfProperty(base, property);

        if (result == null)
        {
            return base;
        }

        return result;
    }

    private Object getValueOfProperty(Object base, String property)
    {
        property = property.substring(0, 1).toUpperCase() + property.substring(1, property.length());

        Class targetClass = ProxyUtils.getUnproxiedClass(base.getClass());

        Method targetMethod = ReflectionUtils.tryToGetMethod(targetClass, "get" + property);

        if (targetMethod == null)
        {
            targetMethod = ReflectionUtils.tryToGetMethod(targetClass, "is" + property);
        }

        if (targetMethod == null)
        {
            throw new IllegalStateException(
                    "class " + targetClass + " has no public get/is " + property.toLowerCase());
        }
        return ReflectionUtils.tryToInvokeMethod(base, targetMethod);
    }

    private void processFoundGroups(ExtValBeanValidationContext extValBeanValidationContext,
                                    String currentViewId,
                                    String clientId,
                                    List<Class> foundGroupsForPropertyValidation)
    {
        /*
         * add found groups to context
         */
        for (Class currentGroupClass : foundGroupsForPropertyValidation)
        {
            extValBeanValidationContext.addGroup(currentGroupClass, currentViewId, clientId);
        }
    }

    private void processRestrictedGroups(ExtValBeanValidationContext extValBeanValidationContext,
                                         String currentViewId,
                                         String clientId,
                                         List<Class> restrictedGroupsForPropertyValidation)
    {
        /*
         * add restricted groups
         */
        for (Class currentGroupClass : restrictedGroupsForPropertyValidation)
        {
            extValBeanValidationContext.restrictGroup(currentGroupClass, currentViewId, clientId);
        }
    }

    private void initModelValidation(ExtValBeanValidationContext extValBeanValidationContext,
                                     UIComponent component,
                                     PropertyDetails propertyDetails,
                                     List<ModelValidationEntry> modelValidationEntryList,
                                     List<Class> restrictedGroupsForModelValidation)
    {
        /*
         * add model validation entry list
         */
        for (ModelValidationEntry modelValidationEntry : modelValidationEntryList)
        {
            for (Class restrictedGroup : restrictedGroupsForModelValidation)
            {
                modelValidationEntry.removeGroup(restrictedGroup);
            }

            if (modelValidationEntry.getGroups().length > 0)
            {
                if (modelValidationEntry.getValidationTargets().isEmpty())
                {
                    modelValidationEntry.addValidationTarget(propertyDetails.getBaseObject());
                }
                modelValidationEntry.setComponent(component);
                extValBeanValidationContext.addModelValidationEntry(modelValidationEntry);
            }
        }
    }

    @ToDo(value = Priority.MEDIUM, description = "test proxy support")
    private void transferGroupValidationInformationToFoundGroups(
            Class<?> classToInspect,
            Object objectToInspect,
            List<Class> foundGroupsForPropertyValidation,
            List<Class> restrictedGroupsForPropertyValidation,
            List<ModelValidationEntry> modelValidationEntryList,
            List<Class> restrictedGroupsForModelValidation,
            String activeViewId,
            boolean processModelValidation)
    {
        if (classToInspect.isAnnotationPresent(BeanValidation.class))
        {
            tryToProcessMetaData(classToInspect.getAnnotation(BeanValidation.class),
                    objectToInspect,
                    foundGroupsForPropertyValidation,
                    restrictedGroupsForPropertyValidation,
                    modelValidationEntryList,
                    restrictedGroupsForModelValidation,
                    activeViewId,
                    processModelValidation);
        }
        else if (classToInspect.isAnnotationPresent(BeanValidation.List.class))
        {
            for (BeanValidation currentBeanValidation :
                    (classToInspect.getAnnotation(BeanValidation.List.class)).value())
            {
                tryToProcessMetaData(currentBeanValidation,
                        objectToInspect,
                        foundGroupsForPropertyValidation,
                        restrictedGroupsForPropertyValidation,
                        modelValidationEntryList,
                        restrictedGroupsForModelValidation,
                        activeViewId,
                        processModelValidation);
            }
        }
    }

    private void processInterfaces(Class currentClass,
                                   Object metaDataSourceObject,
                                   List<Class> foundGroupsForPropertyValidation,
                                   List<Class> restrictedGroupsForPropertyValidation,
                                   List<ModelValidationEntry> modelValidationEntryList,
                                   List<Class> restrictedGroupsForModelValidation,
                                   String activeViewId,
                                   boolean processModelValidation)
    {
        for (Class currentInterface : currentClass.getInterfaces())
        {
            transferGroupValidationInformationToFoundGroups(
                    currentClass,
                    metaDataSourceObject,
                    foundGroupsForPropertyValidation,
                    restrictedGroupsForPropertyValidation,
                    modelValidationEntryList,
                    restrictedGroupsForModelValidation,
                    activeViewId,
                    processModelValidation);

            processInterfaces(currentInterface, metaDataSourceObject,
                    foundGroupsForPropertyValidation,
                    restrictedGroupsForPropertyValidation,
                    modelValidationEntryList,
                    restrictedGroupsForModelValidation,
                    activeViewId,
                    processModelValidation);
        }
    }

    private void tryToProcessMetaData(BeanValidation beanValidation,
                                      Object metaDataSourceObject,
                                      List<Class> foundGroupsForPropertyValidation,
                                      List<Class> restrictedGroupsForPropertyValidation,
                                      List<ModelValidationEntry> modelValidationEntryList,
                                      List<Class> restrictedGroupsForModelValidation,
                                      String activeViewId,
                                      boolean processModelValidation)
    {
        for (String currentViewId : beanValidation.viewIds())
        {
            if (useMetaDataForViewId(beanValidation, currentViewId, activeViewId))
            {
                processMetaData(beanValidation,
                        metaDataSourceObject,
                        foundGroupsForPropertyValidation,
                        restrictedGroupsForPropertyValidation,
                        modelValidationEntryList,
                        restrictedGroupsForModelValidation,
                        processModelValidation);
                break;
            }
        }
    }

    private boolean useMetaDataForViewId(BeanValidation beanValidation, String viewId, String activeViewId)
    {
        return (viewId.equals(activeViewId) ||
                viewId.equals("*")) && isValidationPermitted(beanValidation);
    }

    private void processMetaData(BeanValidation beanValidation,
                                 Object metaDataSourceObject,
                                 List<Class> foundGroupsForPropertyValidation,
                                 List<Class> restrictedGroupsForPropertyValidation,
                                 List<ModelValidationEntry> modelValidationEntryList,
                                 List<Class> restrictedGroupsForModelValidation,
                                 boolean processModelValidation)
    {
        if (processModelValidation && isModelValidation(beanValidation))
        {
            addModelValidationEntry(
                    beanValidation, metaDataSourceObject,
                    modelValidationEntryList, restrictedGroupsForModelValidation);
        }
        else if (!isModelValidation(beanValidation))
        {
            processGroups(
                    beanValidation, foundGroupsForPropertyValidation, restrictedGroupsForPropertyValidation);
        }
    }

    private boolean isValidationPermitted(BeanValidation beanValidation)
    {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        for (String condition : beanValidation.conditions())
        {
            if (elHelper.isELTermWellFormed(condition) &&
                    elHelper.isELTermValid(facesContext, condition))
            {
                if (Boolean.TRUE.equals(elHelper.getValueOfExpression(
                        facesContext, new ValueBindingExpression(condition))))
                {
                    return true;
                }
            }
            else
            {
                this.logger.severe("an invalid condition is used: " + condition);
            }
        }
        return false;
    }

    private boolean isModelValidation(BeanValidation beanValidation)
    {
        return beanValidation.modelValidation().isActive();
    }

    private void addModelValidationEntry(BeanValidation beanValidation,
                                         Object metaDataSourceObject,
                                         List<ModelValidationEntry> modelValidationEntryList,
                                         List<Class> restrictedGroupsForModelValidation)
    {
        ModelValidationEntry modelValidationEntry = new ModelValidationEntry();

        modelValidationEntry.setGroups(Arrays.asList(beanValidation.useGroups()));
        modelValidationEntry.setDisplayMessageInline(beanValidation.modelValidation().displayInline());
        modelValidationEntry.setCustomMessage(beanValidation.modelValidation().message());
        modelValidationEntry.setMetaDataSourceObject(metaDataSourceObject);

        Object validationTarget;
        for (String validationTargetExpression : beanValidation.modelValidation().validationTargets())
        {
            if (ModelValidation.DEFAULT.equals(validationTargetExpression))
            {
                continue;
            }

            validationTarget = tryToResolveValidationTargetExpression(validationTargetExpression);
            if (validationTarget != null)
            {
                modelValidationEntry.addValidationTarget(validationTarget);
            }
        }

        if (beanValidation.restrictGroups().length > 0)
        {
            restrictedGroupsForModelValidation.addAll(Arrays.asList(beanValidation.restrictGroups()));
        }

        if (modelValidationEntry.getValidationTargets().isEmpty())
        {
            modelValidationEntry.addValidationTarget(metaDataSourceObject);
        }

        modelValidationEntryList.add(modelValidationEntry);
    }

    private Object tryToResolveValidationTargetExpression(String validationTargetExpression)
    {
        ValueBindingExpression valueBindingExpression = new ValueBindingExpression(validationTargetExpression);
        return this.elHelper.getValueOfExpression(FacesContext.getCurrentInstance(), valueBindingExpression);
    }

    private void processGroups(BeanValidation beanValidation,
                               List<Class> foundGroupsForPropertyValidation,
                               List<Class> restrictedGroupsForPropertyValidation)
    {
        foundGroupsForPropertyValidation.addAll(Arrays.asList(beanValidation.useGroups()));

        if (beanValidation.restrictGroups().length > 0)
        {
            restrictedGroupsForPropertyValidation.addAll(Arrays.asList(beanValidation.restrictGroups()));
        }
    }

    String createLabeledMessage(String violationMessage, boolean isDetailMessage)
    {
        return this.labeledMessageInternals.createLabeledMessage(violationMessage, isDetailMessage);
    }

    FacesMessage.Severity calcSeverity(ConstraintViolation<Object> violation)
    {
        for (Class<? extends Payload> payload : violation.getConstraintDescriptor().getPayload())
        {
            if (ExtValUtils.getValidationParameterClassFor(ViolationSeverity.Warn.class).isAssignableFrom(payload))
            {
                return FacesMessage.SEVERITY_WARN;
            }
            else if (ExtValUtils
                    .getValidationParameterClassFor(ViolationSeverity.Info.class).isAssignableFrom(payload))
            {
                return FacesMessage.SEVERITY_INFO;
            }
            else if (ExtValUtils
                    .getValidationParameterClassFor(ViolationSeverity.Fatal.class).isAssignableFrom(payload))
            {
                return FacesMessage.SEVERITY_FATAL;
            }
        }
        return FacesMessage.SEVERITY_ERROR;
    }

    void processFacesMessage(FacesContext facesContext, UIComponent uiComponent,
                             List<FacesMessageHolder> facesMessageHolderList, FacesMessage facesMessage)
    {
        FacesMessageHolder facesMessageHolder = new FacesMessageHolder(facesMessage);

        facesMessageHolder.setClientId(uiComponent.getClientId(facesContext));

        facesMessageHolderList.add(facesMessageHolder);
    }

    boolean executeAfterThrowingInterceptors(UIComponent uiComponent,
                                             Object convertedObject,
                                             ValidatorException validatorException)
    {
        return ExtValUtils.executeAfterThrowingInterceptors(
                uiComponent,
                null,
                convertedObject,
                validatorException,
                null);
    }

    boolean isMessageTextUnchanged(
            ValidatorException validatorException, String violationSummaryMessage, String violationDetailMessage)
    {
        return violationSummaryMessage.equals(validatorException.getFacesMessage().getSummary()) &&
                violationDetailMessage.equals(validatorException.getFacesMessage().getDetail());
    }

    ValidatorException createValidatorException(
            String violationSummaryMessage, String violationDetailMessage, FacesMessage.Severity severity)
    {
        return new ValidatorException(
                ExtValUtils.createFacesMessage(severity, violationSummaryMessage, violationDetailMessage));
    }

    List<FacesMessageHolder> getFacesMessageListWithLowSeverity(
            List<FacesMessageHolder> violationMessages)
    {
        List<FacesMessageHolder> result = new ArrayList<FacesMessageHolder>();

        for (FacesMessageHolder facesMessageHolder : violationMessages)
        {
            if (FacesMessage.SEVERITY_WARN.equals(facesMessageHolder.getFacesMessage().getSeverity()) ||
                    FacesMessage.SEVERITY_INFO.equals(facesMessageHolder.getFacesMessage().getSeverity()))
            {
                result.add(facesMessageHolder);
            }
        }
        return result;
    }

    List<FacesMessageHolder> getFacesMessageListWithHighSeverity(
            List<FacesMessageHolder> violationMessageHolderList)
    {
        List<FacesMessageHolder> result = new ArrayList<FacesMessageHolder>();

        for (FacesMessageHolder facesMessageHolder : violationMessageHolderList)
        {
            if (FacesMessage.SEVERITY_ERROR.equals(facesMessageHolder.getFacesMessage().getSeverity()) ||
                    FacesMessage.SEVERITY_FATAL.equals(facesMessageHolder.getFacesMessage().getSeverity()))
            {
                result.add(facesMessageHolder);
            }
        }
        return result;
    }

    void addMessages(List<FacesMessageHolder> facesMessageHolderListWithLowSeverity)
    {
        for (FacesMessageHolder facesMessageHolder : facesMessageHolderListWithLowSeverity)
        {
            ExtValUtils.tryToAddViolationMessageForComponentId(
                    facesMessageHolder.getClientId(), facesMessageHolder.getFacesMessage());
        }
    }
}
