/*
 * Copyright The WildFly Authors
 * SPDX-License-Identifier: Apache-2.0
 */

package org.jboss.as.logging.capabilities;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.logging.Handler;

import org.jboss.as.controller.CapabilityReferenceRecorder;
import org.jboss.as.controller.capability.RuntimeCapability;
import org.jboss.as.logging.filters.Filters;
import org.jboss.as.logging.handlers.AbstractHandlerDefinition;
import org.jboss.as.logging.loggers.LoggerAttributes;

/**
 * Logging capabilities. Not for use outside the logging extension.
 *
 * @author <a href="mailto:jperkins@redhat.com">James R. Perkins</a>
 */
public class Capabilities {

    /**
     * Reference to an SSL context.
     */
    public static final String SSL_CONTEXT_CAPABILITY = "org.wildfly.security.ssl-context";

    /**
     * A capability for logging filter.
     */
    public static final RuntimeCapability<Void> FILTER_CAPABILITY = RuntimeCapability.Builder.of("org.wildfly.logging.filter", true)
            .setDynamicNameMapper(LoggingProfileNameMapper.INSTANCE)
            .build();

    /**
     * A capability for logging formatters.
     */
    public static final RuntimeCapability<Void> FORMATTER_CAPABILITY = RuntimeCapability.Builder.of("org.wildfly.logging.formatter", true)
            .setDynamicNameMapper(LoggingProfileNameMapper.INSTANCE)
            .build();

    /**
     * A capability for logging handlers.
     * <p>
     * Note that while this capability can expose a {@linkplain Handler handler} it's not required. It's only used in
     * cases where a handler might need to register a service. This is not needed in most cases.
     * </p>
     */
    public static final RuntimeCapability<Void> HANDLER_CAPABILITY = RuntimeCapability.Builder.of("org.wildfly.logging.handler", true, Handler.class)
            .setDynamicNameMapper(LoggingProfileNameMapper.INSTANCE)
            .build();

    /**
     * A capability for loggers.
     */
    public static final RuntimeCapability<Void> LOGGER_CAPABILITY = RuntimeCapability.Builder.of("org.wildfly.logging.logger", true)
            .setDynamicNameMapper(LoggingProfileNameMapper.INSTANCE)
            .build();

    /**
     * A capability recorder for configuring a filter on a handler.
     */
    public static final CapabilityReferenceRecorder HANDLER_FILTER_REFERENCE_RECORDER = new LoggingProfileCapabilityRecorder(
            HANDLER_CAPABILITY.getName(), FILTER_CAPABILITY.getName(), (values, attributeName) -> {
        final Collection<String> result = new ArrayList<>();
        if (attributeName.equals(AbstractHandlerDefinition.FILTER_SPEC.getName())) {
            for (String v : values) {
                result.addAll(Filters.getCustomFilterNames(v));
            }
        } else {
            Collections.addAll(result, values);
        }
        return result;
    });

    /**
     * A capability recorder for configuring a formatter on a handler.
     */
    public static final CapabilityReferenceRecorder HANDLER_FORMATTER_REFERENCE_RECORDER = new LoggingProfileCapabilityRecorder(
            HANDLER_CAPABILITY.getName(), FORMATTER_CAPABILITY.getName());

    /**
     * A capability recorder for configuring sub-handlers on a handler.
     */
    public static final CapabilityReferenceRecorder HANDLER_REFERENCE_RECORDER = new LoggingProfileCapabilityRecorder(
            HANDLER_CAPABILITY.getName(), HANDLER_CAPABILITY.getName());

    /**
     * A capability recorder for configuring filters on a logger.
     */
    public static final CapabilityReferenceRecorder LOGGER_FILTER_REFERENCE_RECORDER = new LoggingProfileCapabilityRecorder(
            LOGGER_CAPABILITY.getName(), FILTER_CAPABILITY.getName(), (values, attributeName) -> {
        final Collection<String> result = new ArrayList<>();
        if (attributeName.equals(LoggerAttributes.FILTER_SPEC.getName())) {
            for (String v : values) {
                result.addAll(Filters.getCustomFilterNames(v));
            }
        } else {
            Collections.addAll(result, values);
        }
        return result;
    });

    /**
     * A capability recorder for configuring handlers on a logger.
     */
    public static final CapabilityReferenceRecorder LOGGER_HANDLER_REFERENCE_RECORDER = new LoggingProfileCapabilityRecorder(
            LOGGER_CAPABILITY.getName(), HANDLER_CAPABILITY.getName());
}
