/*
 * 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 org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
import org.apache.logging.log4j.plugins.inject.AbstractConfigurationInjector;
import org.apache.logging.log4j.util.NameUtil;
import org.apache.logging.log4j.util.StringBuilders;
import org.apache.logging.log4j.util.Strings;

import java.lang.reflect.Type;
import java.util.Collections;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;

/**
 * @deprecated Provided to support legacy plugins.
 */
// copy of PluginAttributeInjector
public class PluginAttributeVisitor extends AbstractConfigurationInjector<PluginAttribute, Configuration> {

    private static final Map<Type, Function<PluginAttribute, Object>> DEFAULT_VALUE_EXTRACTORS;

    static {
        final Map<Class<?>, Function<PluginAttribute, Object>> extractors = new ConcurrentHashMap<>();
        extractors.put(int.class, PluginAttribute::defaultInt);
        extractors.put(Integer.class, PluginAttribute::defaultInt);
        extractors.put(long.class, PluginAttribute::defaultLong);
        extractors.put(Long.class, PluginAttribute::defaultLong);
        extractors.put(boolean.class, PluginAttribute::defaultBoolean);
        extractors.put(Boolean.class, PluginAttribute::defaultBoolean);
        extractors.put(float.class, PluginAttribute::defaultFloat);
        extractors.put(Float.class, PluginAttribute::defaultFloat);
        extractors.put(double.class, PluginAttribute::defaultDouble);
        extractors.put(Double.class, PluginAttribute::defaultDouble);
        extractors.put(byte.class, PluginAttribute::defaultByte);
        extractors.put(Byte.class, PluginAttribute::defaultByte);
        extractors.put(char.class, PluginAttribute::defaultChar);
        extractors.put(Character.class, PluginAttribute::defaultChar);
        extractors.put(short.class, PluginAttribute::defaultShort);
        extractors.put(Short.class, PluginAttribute::defaultShort);
        extractors.put(Class.class, PluginAttribute::defaultClass);
        DEFAULT_VALUE_EXTRACTORS = Collections.unmodifiableMap(extractors);
    }

    @Override
    public void inject(final Object factory) {
        final Optional<String> value = findAndRemoveNodeAttribute().map(stringSubstitutionStrategy);
        if (value.isPresent()) {
            configurationBinder.bindString(factory, value.get());
        } else {
            injectDefaultValue(factory);
        }
    }

    private void injectDefaultValue(final Object factory) {
        final Function<PluginAttribute, Object> extractor = DEFAULT_VALUE_EXTRACTORS.get(conversionType);
        if (extractor != null) {
            final Object value = extractor.apply(annotation);
            debugLog(value);
            configurationBinder.bindObject(factory, value);
        } else {
            final String value = stringSubstitutionStrategy.apply(annotation.defaultString());
            if (Strings.isNotBlank(value)) {
                debugLog(value);
                configurationBinder.bindString(factory, value);
            }
        }
    }

    private void debugLog(final Object value) {
        final Object debugValue = annotation.sensitive() ? NameUtil.md5(value + getClass().getName()) : value;
        StringBuilders.appendKeyDqValue(debugLog, name, debugValue);
    }
}
