/*
 * 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.layout.json.template.util;

import org.apache.logging.log4j.plugins.convert.TypeConverter;
import org.apache.logging.log4j.plugins.convert.TypeConverterRegistry;
import org.assertj.core.api.Assertions;
import org.junit.Test;

import java.util.ArrayDeque;
import java.util.concurrent.ArrayBlockingQueue;

public class RecyclerFactoriesTest {

    @Test
    public void test_RecyclerFactoryConverter() throws Exception {

        // Check if the type converter is registered.
        final TypeConverter<?> converter = TypeConverterRegistry
                .getInstance()
                .findCompatibleConverter(RecyclerFactory.class);
        Assertions.assertThat(converter).isNotNull();

        // Check dummy recycler factory.
        {
            final Object actualDummyRecyclerFactory = converter.convert("dummy");
            Assertions
                    .assertThat(actualDummyRecyclerFactory)
                    .isSameAs(DummyRecyclerFactory.getInstance());
        }

        // Check thread-local recycler factory.
        {
            final Object actualThreadLocalRecyclerFactory = converter.convert("threadLocal");
            Assertions
                    .assertThat(actualThreadLocalRecyclerFactory)
                    .isSameAs(ThreadLocalRecyclerFactory.getInstance());
        }

        // Check queueing recycler factory.
        {
            final Object actualQueueingRecyclerFactory = converter.convert("queue");
            Assertions
                    .assertThat(actualQueueingRecyclerFactory)
                    .isInstanceOf(QueueingRecyclerFactory.class);
        }

        // Check queueing recycler factory with supplier.
        {
            final Object recyclerFactory = converter.convert(
                    "queue:supplier=java.util.ArrayDeque.new");
            Assertions
                    .assertThat(recyclerFactory)
                    .isInstanceOf(QueueingRecyclerFactory.class);
            final QueueingRecyclerFactory queueingRecyclerFactory =
                    (QueueingRecyclerFactory) recyclerFactory;
            final Recycler<Object> recycler =
                    queueingRecyclerFactory.create(Object::new);
            Assertions
                    .assertThat(recycler)
                    .isInstanceOf(QueueingRecycler.class);
            final QueueingRecycler<Object> queueingRecycler =
                    (QueueingRecycler<Object>) recycler;
            Assertions
                    .assertThat(queueingRecycler.getQueue())
                    .isInstanceOf(ArrayDeque.class);
        }

        // Check queueing recycler factory with capacity.
        {
            final Object actualQueueingRecyclerFactory = converter.convert(
                    "queue:capacity=100");
            Assertions
                    .assertThat(actualQueueingRecyclerFactory)
                    .isInstanceOf(QueueingRecyclerFactory.class);
        }

        // Check queueing recycler factory with supplier and capacity.
        {
            final Object recyclerFactory = converter.convert(
                    "queue:" +
                            "supplier=java.util.concurrent.ArrayBlockingQueue.new," +
                            "capacity=100");
            Assertions
                    .assertThat(recyclerFactory)
                    .isInstanceOf(QueueingRecyclerFactory.class);
            final QueueingRecyclerFactory queueingRecyclerFactory =
                    (QueueingRecyclerFactory) recyclerFactory;
            final Recycler<Object> recycler =
                    queueingRecyclerFactory.create(Object::new);
            Assertions
                    .assertThat(recycler)
                    .isInstanceOf(QueueingRecycler.class);
            final QueueingRecycler<Object> queueingRecycler =
                    (QueueingRecycler<Object>) recycler;
            Assertions
                    .assertThat(queueingRecycler.getQueue())
                    .isInstanceOf(ArrayBlockingQueue.class);
            final ArrayBlockingQueue<Object> queue =
                    (ArrayBlockingQueue<Object>) queueingRecycler.getQueue();
            Assertions.assertThat(queue.remainingCapacity()).isEqualTo(100);
        }

    }

}
