/*
 * 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.syncope.core.provisioning.java.data;

import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.commons.jexl3.JexlContext;
import org.apache.commons.jexl3.MapContext;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.common.lib.to.AnyTO;
import org.apache.syncope.common.lib.to.EntityTO;
import org.apache.syncope.common.lib.types.AttrSchemaType;
import org.apache.syncope.core.persistence.api.entity.Any;
import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
import org.apache.syncope.core.persistence.api.entity.resource.Item;
import org.apache.syncope.core.provisioning.api.DerAttrHandler;
import org.apache.syncope.core.provisioning.api.data.JEXLItemTransformer;
import org.apache.syncope.core.provisioning.api.jexl.JexlUtils;
import org.springframework.beans.factory.annotation.Autowired;

public class JEXLItemTransformerImpl implements JEXLItemTransformer {

    @Autowired
    private DerAttrHandler derAttrHandler;

    @Autowired
    private AnyUtilsFactory anyUtilsFactory;

    private String propagationJEXL;

    private String pullJEXL;

    @Override
    public void setPropagationJEXL(final String propagationJEXL) {
        this.propagationJEXL = propagationJEXL;
    }

    @Override
    public void setPullJEXL(final String pullJEXL) {
        this.pullJEXL = pullJEXL;
    }

    protected AttrSchemaType beforePropagation(final PlainAttrValue value, final Any<?> any) {
        JexlContext jexlContext = new MapContext();
        if (any != null) {
            JexlUtils.addFieldsToContext(any, jexlContext);
            JexlUtils.addPlainAttrsToContext(any.getPlainAttrs(), jexlContext);
            JexlUtils.addDerAttrsToContext(any, derAttrHandler, jexlContext);
        }
        jexlContext.set("value", value.getValue());

        Object tValue = JexlUtils.evaluate(propagationJEXL, jexlContext);

        value.setBinaryValue(null);
        value.setBooleanValue(null);
        value.setDateValue(null);
        value.setDoubleValue(null);
        value.setLongValue(null);
        value.setStringValue(null);

        if (tValue instanceof byte[]) {
            value.setBinaryValue((byte[]) tValue);
            return AttrSchemaType.Binary;
        }

        if (tValue instanceof Boolean) {
            value.setBooleanValue((Boolean) tValue);
            return AttrSchemaType.Boolean;
        }

        if (tValue instanceof OffsetDateTime) {
            value.setDateValue((OffsetDateTime) tValue);
            return AttrSchemaType.Date;
        }

        if (tValue instanceof Double) {
            value.setDoubleValue((Double) tValue);
            return AttrSchemaType.Double;
        }

        if (tValue instanceof Long) {
            value.setLongValue((Long) tValue);
            return AttrSchemaType.Long;
        }

        if (tValue != null) {
            value.setStringValue(tValue.toString());
        }
        return AttrSchemaType.String;
    }

    @Override
    public Pair<AttrSchemaType, List<PlainAttrValue>> beforePropagation(
            final Item item,
            final Any<?> any,
            final AttrSchemaType schemaType,
            final List<PlainAttrValue> values) {

        if (StringUtils.isBlank(propagationJEXL)) {
            return JEXLItemTransformer.super.beforePropagation(item, any, schemaType, values);
        }

        AtomicReference<AttrSchemaType> tType = new AtomicReference<>();
        if (values.isEmpty()) {
            PlainAttrValue value = anyUtilsFactory.getInstance(any).newPlainAttrValue();
            tType.set(beforePropagation(value, any));
            values.add(value);
        } else {
            values.forEach(value -> tType.set(beforePropagation(value, any)));
        }

        return Pair.of(tType.get(), values);
    }

    @Override
    public List<Object> beforePull(
            final Item item,
            final EntityTO entityTO,
            final List<Object> values) {

        if (StringUtils.isNotBlank(pullJEXL) && values != null) {
            List<Object> newValues = new ArrayList<>(values.size());
            values.forEach(value -> {
                JexlContext jexlContext = new MapContext();
                jexlContext.set("value", value);
                JexlUtils.addFieldsToContext(entityTO, jexlContext);
                if (entityTO instanceof AnyTO) {
                    JexlUtils.addAttrsToContext(((AnyTO) entityTO).getPlainAttrs(), jexlContext);
                    JexlUtils.addAttrsToContext(((AnyTO) entityTO).getDerAttrs(), jexlContext);
                    JexlUtils.addAttrsToContext(((AnyTO) entityTO).getVirAttrs(), jexlContext);
                }

                newValues.add(JexlUtils.evaluate(pullJEXL, jexlContext));
            });

            return newValues;
        }

        return JEXLItemTransformer.super.beforePull(item, entityTO, values);
    }
}
