/*
 * Licensed 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.sling.resource.filter.impl;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.Function;

import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.resource.filter.impl.node.Node;
import org.apache.sling.resource.filter.impl.predicates.Null;
import org.apache.sling.resource.filter.impl.script.FilterParserConstants;

public class ComparisonVisitor implements Visitor<Function<Resource, Object>> {

    private Context context;

    public ComparisonVisitor(Context context) {
        this.context = context;
        context.setComparionVisitor(this);
    }

    @Override
    public Function<Resource, Object> visit(Node node) {
        switch (node.kind) {
        case FilterParserConstants.FUNCTION_NAME:
            return functionHandler(node);
        case FilterParserConstants.NULL:
            return resource -> new Null();
        case FilterParserConstants.NUMBER:
            return resource -> numericHandler(node.text);
        case FilterParserConstants.OFFSETDATETIME:
            return resource -> OffsetDateTime.parse(node.text).toInstant();
        case FilterParserConstants.DATETIME:
            return resource -> LocalDateTime.parse(node.text).atOffset(ZoneOffset.UTC).toInstant();
        case FilterParserConstants.DATE:
            return resource -> LocalDate.parse(node.text).atStartOfDay(ZoneOffset.UTC).toInstant();
        case FilterParserConstants.PROPERTY:
            return resource -> {
                Object value = valueMapOf(resource).get(node.text);
                if (value instanceof Boolean) {
                    return value.toString();
                }
                if (value instanceof Calendar) {
                    return ((Calendar) value).toInstant();
                }
                return value;
            };
        case FilterParserConstants.DYNAMIC_ARG:
            return resource -> {
                String argument = node.text;
                Optional<Object> arg = context.getArgument(argument);
                if (!arg.isPresent()) {
                    throw new NoSuchElementException(String.format("No value present for '%s'",argument));
                }
                return arg.get();
            };
        default:
            return resource -> node.text;
        }
    }

    private ValueMap valueMapOf(Resource resource) {
        if (resource == null || ResourceUtil.isNonExistingResource(resource)) {
            return ValueMap.EMPTY;
        }
        return resource.adaptTo(ValueMap.class);
    }

    private static Object dateHandler(Object[] arguments) {
        if (arguments.length == 0) {
            return Instant.now();
        }
        String dateString = arguments[0].toString();
        String formatString = null;
        if (arguments.length > 1) {
            formatString = arguments[1].toString();
            SimpleDateFormat dateFormat = new SimpleDateFormat(formatString);
            try {
                return Instant.ofEpochMilli(dateFormat.parse(dateString).getTime());
            } catch (ParseException e) {
                return null;
            }
        } else {
            return DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse(dateString, OffsetDateTime::from).toInstant();
        }
    }
    
    private Function<Resource, Object> functionHandler(Node node){
        // will only get here in the case of the 'FUNCTION' switch case
        switch (node.text) {
        case "name":
            return Resource::getName;
        case "path":
            return Resource::getPath;
        case "date":
            return resource -> {
                Object[] arguments = node.visitChildren(this).stream().map(funct -> funct.apply(resource))
                        .toArray();
                return dateHandler(arguments);
            };
        default:
            Optional<BiFunction<Object[], Resource, Object>> temp = context.getFunction(node.text);
            if (temp.isPresent()) {
                final List<Function<Resource, Object>> children2 = node.visitChildren(this);
                return resource -> {
                    Object[] arguments = children2.stream().map(funct -> funct.apply(resource)).toArray();
                    return temp.get().apply(arguments, resource);
                };
            }
        }
        return null;
    }
    
    private static Number numericHandler(String numberText) {
        Number numericValue = null;
        try {
            numericValue = Integer.valueOf(numberText);
        } catch (NumberFormatException nfe1) {
            try {
                numericValue = new BigDecimal(numberText);
            } catch (NumberFormatException nfe2) {
                // swallow
            }
        }
        return numericValue;
    }

}
