/*
 * 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.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Stack;
import java.util.concurrent.CountDownLatch;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.appender.AsyncAppender;
import org.apache.logging.log4j.core.config.LoggerConfig;

import com.lmax.disruptor.dsl.Disruptor;

/**
 * Tests queue full scenarios abstract superclass.
 */
public abstract class QueueFullAbstractTest {
    protected static boolean TRACE = true;
    protected BlockingAppender blockingAppender;
    protected Unlocker unlocker;

    protected static void TRACE(Object msg) {
        if (TRACE) {
            System.out.println(msg);
        }
    }

    class Unlocker extends Thread {
        final CountDownLatch countDownLatch;
        Unlocker(CountDownLatch countDownLatch) {
            this.countDownLatch = countDownLatch;
        }
        @Override
        public void run() {
            try {
                countDownLatch.await();
                TRACE("Unlocker activated. Sleeping 500 millis before taking action...");
                Thread.sleep(500);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            TRACE("Unlocker signalling BlockingAppender to proceed...");
            blockingAppender.countDownLatch.countDown();
        }
    }

    class DomainObject {
        private Logger innerLogger = LogManager.getLogger(DomainObject.class);
        final int count;
        DomainObject(int loggingCount) {
            this.count = loggingCount;
        }

        @Override
        public String toString() {
            for (int i = 0; i < count; i++) {
                TRACE("DomainObject decrementing unlocker countdown latch before logging. Count was " + unlocker.countDownLatch.getCount());
                unlocker.countDownLatch.countDown();
                TRACE("DomainObject logging message " + i  + ". Remaining capacity=" + asyncRemainingCapacity(innerLogger));
                innerLogger.info("Logging in toString() #" + i);
            }
            return "Who's bad?!";
        }
    }

    static Stack transform(final List<LogEvent> logEvents) {
        final List<String> filtered = new ArrayList<>(logEvents.size());
        for (LogEvent event : logEvents) {
            filtered.add(event.getMessage().getFormattedMessage());
        }
        Collections.reverse(filtered);
        Stack<String> result = new Stack<>();
        result.addAll(filtered);
        return result;
    }

    static long asyncRemainingCapacity(Logger logger) {
        if (logger instanceof AsyncLogger) {
            try {
                Field f = field(AsyncLogger.class, "loggerDisruptor");
                return ((AsyncLoggerDisruptor) f.get(logger)).getDisruptor().getRingBuffer().remainingCapacity();
            } catch (Exception ex) {
                throw new RuntimeException(ex);
            }
        } else {
            LoggerConfig loggerConfig = ((org.apache.logging.log4j.core.Logger) logger).get();
            if (loggerConfig instanceof AsyncLoggerConfig) {
                try {
                    Object delegate = field(AsyncLoggerConfig.class, "delegate").get(loggerConfig);
                    return ((Disruptor) field(AsyncLoggerConfigDisruptor.class, "disruptor").get(delegate)).getRingBuffer().remainingCapacity();
                } catch (Exception ex) {
                    throw new RuntimeException(ex);
                }
            } else {
                Appender async = loggerConfig.getAppenders().get("async");
                if (async instanceof AsyncAppender) {
                    return ((AsyncAppender) async).getQueueCapacity();
                }
            }
        }
        throw new IllegalStateException("Neither Async Loggers nor AsyncAppender are configured");
    }
    private static Field field(Class<?> c, String name) throws NoSuchFieldException {
        Field f = c.getDeclaredField(name);
        f.setAccessible(true);
        return f;
    }
}
