/*
 * 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.async;

import java.util.Collection;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;

import org.apache.logging.log4j.plugins.Node;
import org.apache.logging.log4j.plugins.Plugin;
import org.apache.logging.log4j.plugins.PluginAttribute;
import org.apache.logging.log4j.plugins.PluginFactory;
import org.jctools.queues.MpscArrayQueue;

/**
 * Factory for creating instances of BlockingQueues backed by JCTools {@link MpscArrayQueue}.
 *
 * @since 2.7
 */
@Plugin(name = "JCToolsBlockingQueue", category = Node.CATEGORY, elementType = BlockingQueueFactory.ELEMENT_TYPE)
public class JCToolsBlockingQueueFactory<E> implements BlockingQueueFactory<E> {

    private final WaitStrategy waitStrategy;

    private JCToolsBlockingQueueFactory(final WaitStrategy waitStrategy) {
        this.waitStrategy = waitStrategy;
    }

    @Override
    public BlockingQueue<E> create(final int capacity) {
        return new MpscBlockingQueue<>(capacity, waitStrategy);
    }

    @PluginFactory
    public static <E> JCToolsBlockingQueueFactory<E> createFactory(
        @PluginAttribute(defaultString = "PARK") final WaitStrategy waitStrategy) {
        return new JCToolsBlockingQueueFactory<>(waitStrategy);
    }

    /**
     * BlockingQueue wrapper for JCTools multiple producer single consumer array queue.
     */
    private static final class MpscBlockingQueue<E> extends MpscArrayQueue<E> implements BlockingQueue<E> {

        private final JCToolsBlockingQueueFactory.WaitStrategy waitStrategy;

        MpscBlockingQueue(final int capacity, final JCToolsBlockingQueueFactory.WaitStrategy waitStrategy) {
            super(capacity);
            this.waitStrategy = waitStrategy;
        }

        @Override
        public int drainTo(final Collection<? super E> c) {
            return drainTo(c, capacity());
        }

        @Override
        public int drainTo(final Collection<? super E> c, final int maxElements) {
            return drain(new Consumer<E>() {
                @Override
                public void accept(final E e) {
                    c.add(e);
                }
            }, maxElements);
        }

        @Override
        public boolean offer(final E e, final long timeout, final TimeUnit unit) throws InterruptedException {
            int idleCounter = 0;
            final long timeoutNanos = System.nanoTime() + unit.toNanos(timeout);
            do {
                if (offer(e)) {
                    return true;
                } else if (System.nanoTime() - timeoutNanos > 0) {
                    return false;
                }
                idleCounter = waitStrategy.idle(idleCounter);
            } while (!Thread.interrupted()); //clear interrupted flag
            throw new InterruptedException();
        }

        @Override
        public E poll(final long timeout, final TimeUnit unit) throws InterruptedException {
            int idleCounter = 0;
            final long timeoutNanos = System.nanoTime() + unit.toNanos(timeout);
            do {
                final E result = poll();
                if (result != null) {
                    return result;
                } else if (System.nanoTime() - timeoutNanos > 0) {
                    return null;
                }
                idleCounter = waitStrategy.idle(idleCounter);
            } while (!Thread.interrupted()); //clear interrupted flag
            throw new InterruptedException();
        }

        @Override
        public void put(final E e) throws InterruptedException {
            int idleCounter = 0;
            do {
                if (offer(e)) {
                    return;
                }
                idleCounter = waitStrategy.idle(idleCounter);
            } while (!Thread.interrupted()); //clear interrupted flag
            throw new InterruptedException();
        }

        @Override
        public boolean offer(final E e) {
            //keep 2 cache lines empty to avoid false sharing that will slow the consumer thread when queue is full.
            return offerIfBelowThreshold(e, capacity() - 32);
        }

        @Override
        public int remainingCapacity() {
            return capacity() - size();
        }

        @Override
        public E take() throws InterruptedException {
            int idleCounter = 100;
            do {
                final E result = relaxedPoll();
                if (result != null) {
                    return result;
                }
                idleCounter = waitStrategy.idle(idleCounter);
            } while (!Thread.interrupted()); //clear interrupted flag
            throw new InterruptedException();
        }
    }

    public enum WaitStrategy {
        SPIN(new Idle() {
            @Override
            public int idle(final int idleCounter) {
                return idleCounter + 1;
            }
        }),
        YIELD(new Idle() {
            @Override
            public int idle(final int idleCounter) {
                Thread.yield();
                return idleCounter + 1;
            }
        }),
        PARK(new Idle() {
            @Override
            public int idle(final int idleCounter) {
                LockSupport.parkNanos(1L);
                return idleCounter + 1;
            }
        }),
        PROGRESSIVE(new Idle() {
            @Override
            public int idle(final int idleCounter) {
                if (idleCounter > 200) {
                    LockSupport.parkNanos(1L);
                } else if (idleCounter > 100) {
                    Thread.yield();
                }
                return idleCounter + 1;
            }
        });

        private final Idle idle;

        private int idle(final int idleCounter) {
            return idle.idle(idleCounter);
        }

        WaitStrategy(final Idle idle) {
            this.idle = idle;
        }
    }

    private interface Idle {
        int idle(int idleCounter);
    }

}
