/*
 * 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.logging.log4j.core.config.plugins.visitors;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.Node;
import org.apache.logging.log4j.core.config.plugins.PluginElement;
import org.apache.logging.log4j.core.config.plugins.util.PluginType;

/**
 * PluginVisitor implementation for {@link PluginElement}. Supports arrays as well as singular values.
 */
public class PluginElementVisitor extends AbstractPluginVisitor<PluginElement> {
    public PluginElementVisitor() {
        super(PluginElement.class);
    }

    @Override
    public Object visit(final Configuration configuration, final Node node, final LogEvent event,
                        final StringBuilder log) {
        final String name = this.annotation.value();
        if (this.conversionType.isArray()) {
            setConversionType(this.conversionType.getComponentType());
            final List<Object> values = new ArrayList<>();
            final Collection<Node> used = new ArrayList<>();
            log.append("={");
            boolean first = true;
            for (final Node child : node.getChildren()) {
                final PluginType<?> childType = child.getType();
                if (name.equalsIgnoreCase(childType.getElementName()) ||
                    this.conversionType.isAssignableFrom(childType.getPluginClass())) {
                    if (!first) {
                        log.append(", ");
                    }
                    first = false;
                    used.add(child);
                    final Object childObject = child.getObject();
                    if (childObject == null) {
                        LOGGER.error("Null object returned for {} in {}.", child.getName(), node.getName());
                        continue;
                    }
                    if (childObject.getClass().isArray()) {
                        log.append(Arrays.toString((Object[]) childObject)).append('}');
                        return childObject;
                    }
                    log.append(child.toString());
                    values.add(childObject);
                }
            }
            log.append('}');
            // note that we need to return an empty array instead of null if the types are correct
            if (!values.isEmpty() && !this.conversionType.isAssignableFrom(values.get(0).getClass())) {
                LOGGER.error("Attempted to assign attribute {} to list of type {} which is incompatible with {}.",
                    name, values.get(0).getClass(), this.conversionType);
                return null;
            }
            node.getChildren().removeAll(used);
            // we need to use reflection here because values.toArray() will cause type errors at runtime
            final Object[] array = (Object[]) Array.newInstance(this.conversionType, values.size());
            for (int i = 0; i < array.length; i++) {
                array[i] = values.get(i);
            }
            return array;
        }
        final Node namedNode = findNamedNode(name, node.getChildren());
        if (namedNode == null) {
            log.append(name).append("=null");
            return null;
        }
        log.append(namedNode.getName()).append('(').append(namedNode.toString()).append(')');
        node.getChildren().remove(namedNode);
        return namedNode.getObject();
    }

    private Node findNamedNode(final String name, final Iterable<Node> children) {
        for (final Node child : children) {
            final PluginType<?> childType = child.getType();
            if (childType == null) {
                //System.out.println();
            }
            if (name.equalsIgnoreCase(childType.getElementName()) ||
                this.conversionType.isAssignableFrom(childType.getPluginClass())) {
                // FIXME: check child.getObject() for null?
                // doing so would be more consistent with the array version
                return child;
            }
        }
        return null;
    }
}
