/*
 * 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.geode.logging.log4j.internal.impl;

import java.io.OutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.Core;
import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender;
import org.apache.logging.log4j.core.appender.ConsoleAppender;
import org.apache.logging.log4j.core.appender.ConsoleAppender.Target;
import org.apache.logging.log4j.core.appender.ManagerFactory;
import org.apache.logging.log4j.core.appender.OutputStreamManager;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
import org.apache.logging.log4j.core.config.plugins.validation.constraints.Required;
import org.apache.logging.log4j.core.util.NullOutputStream;

import org.apache.geode.annotations.Immutable;
import org.apache.geode.annotations.VisibleForTesting;
import org.apache.geode.annotations.internal.MakeNotStatic;

/**
 * Wraps {@link ConsoleAppender} with additions defined in {@link PausableAppender} and
 * {@link DebuggableAppender}.
 */
@Plugin(name = GeodeConsoleAppender.PLUGIN_NAME, category = Core.CATEGORY_NAME,
    elementType = Appender.ELEMENT_TYPE, printObject = true)
@SuppressWarnings("unused")
public class GeodeConsoleAppender extends AbstractOutputStreamAppender<OutputStreamManager>
    implements PausableAppender, DebuggableAppender {

  public static final String PLUGIN_NAME = "GeodeConsole";

  private static final boolean START_PAUSED_BY_DEFAULT = false;
  @Immutable
  private static final Target DEFAULT_TARGET = Target.SYSTEM_OUT;
  @MakeNotStatic
  private static final AtomicInteger COUNT = new AtomicInteger();
  @Immutable
  private static final GeodeConsoleManagerFactory MANAGER_FACTORY =
      new GeodeConsoleManagerFactory();

  private final ConsoleAppender delegate;
  private final boolean debug;
  private final List<LogEvent> events;

  private volatile boolean paused;

  protected GeodeConsoleAppender(final String name,
      final Layout<? extends Serializable> layout,
      final Filter filter,
      final OutputStreamManager manager,
      final ConsoleAppender delegate) {
    this(name, layout, filter, manager, true, START_PAUSED_BY_DEFAULT, false, delegate);
  }

  protected GeodeConsoleAppender(final String name,
      final Layout<? extends Serializable> layout,
      final Filter filter,
      final OutputStreamManager manager,
      final boolean ignoreExceptions,
      final boolean startPaused,
      final boolean debug,
      final ConsoleAppender delegate) {
    super(name, layout, filter, ignoreExceptions, true, manager);
    this.delegate = delegate;
    this.debug = debug;
    if (debug) {
      events = Collections.synchronizedList(new ArrayList<>());
    } else {
      events = Collections.emptyList();
    }
    paused = startPaused;
  }

  public static GeodeConsoleAppender createDefaultAppenderForLayout(
      final Layout<? extends Serializable> layout) {
    // this method cannot use the builder class without introducing an infinite loop due to
    // DefaultConfiguration
    return new GeodeConsoleAppender(PLUGIN_NAME + "-" + COUNT.incrementAndGet(), layout, null,
        getDefaultManager(DEFAULT_TARGET, false, false, layout), true, false, false,
        ConsoleAppender.createDefaultAppenderForLayout(layout));
  }

  @PluginBuilderFactory
  public static <B extends Builder<B>> B newBuilder() {
    return new Builder<B>().asBuilder();
  }

  /**
   * Builds GeodeConsoleAppender instances.
   *
   * @param <B> The type to build
   */
  public static class Builder<B extends Builder<B>> extends AbstractOutputStreamAppender.Builder<B>
      implements org.apache.logging.log4j.core.util.Builder<GeodeConsoleAppender> {

    @PluginBuilderAttribute
    @Required
    private Target target = DEFAULT_TARGET;

    @PluginBuilderAttribute
    private boolean follow;

    @PluginBuilderAttribute
    private boolean direct;

    @PluginBuilderAttribute
    private boolean startPaused = START_PAUSED_BY_DEFAULT;

    @PluginBuilderAttribute
    private boolean debug;

    public B setTarget(final Target aTarget) {
      target = aTarget;
      return asBuilder();
    }

    public B setFollow(final boolean shouldFollow) {
      follow = shouldFollow;
      return asBuilder();
    }

    public B setDirect(final boolean shouldDirect) {
      direct = shouldDirect;
      return asBuilder();
    }

    public B setStartPaused(final boolean shouldStartPaused) {
      startPaused = shouldStartPaused;
      return asBuilder();
    }

    public boolean isStartPaused() {
      return debug;
    }

    public B setDebug(final boolean shouldDebug) {
      debug = shouldDebug;
      return asBuilder();
    }

    public boolean isDebug() {
      return debug;
    }

    @Override
    public GeodeConsoleAppender build() {
      ConsoleAppender.Builder delegate = new ConsoleAppender.Builder();
      // AbstractAppender
      delegate.withFilter(getFilter());
      delegate.withName(getName() + "_DELEGATE");
      delegate.withIgnoreExceptions(isIgnoreExceptions());
      delegate.withLayout(getLayout());
      // AbstractOutputStreamAppender
      delegate.withImmediateFlush(isImmediateFlush());
      delegate.withBufferedIo(isBufferedIo());
      delegate.withBufferSize(getBufferSize());
      // ConsoleAppender
      delegate.setTarget(target);
      delegate.setFollow(follow);
      delegate.setDirect(direct);

      Layout<? extends Serializable> layout = getOrCreateLayout(target.getDefaultCharset());
      return new GeodeConsoleAppender(getName(), layout,
          getFilter(), getManager(target, follow, direct, layout),
          isIgnoreExceptions(), startPaused, debug, delegate.build());
    }
  }

  @Override
  public void append(final LogEvent event) {
    if (isPaused()) {
      return;
    }
    delegate.append(event);
    if (debug) {
      events.add(event);
    }
  }

  @Override
  public void start() {
    LOGGER.info("Starting {}.", this);
    delegate.start();
    super.start();
  }

  @Override
  public void stop() {
    LOGGER.info("Stopping {}.", this);
    delegate.stop();
    super.stop();
  }

  @Override
  public void pause() {
    LOGGER.debug("Pausing {}.", this);
    paused = true;
  }

  @Override
  public void resume() {
    LOGGER.debug("Resuming {}.", this);
    paused = false;
  }

  @Override
  public boolean isPaused() {
    return paused;
  }

  @Override
  public void clearLogEvents() {
    events.clear();
  }

  @Override
  public List<LogEvent> getLogEvents() {
    return events;
  }

  @Override
  public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode()) + ":" + getName()
        + " {paused=" + paused + ", debug=" + debug + ", delegate=" + delegate + "}";
  }

  @VisibleForTesting
  ConsoleAppender getDelegate() {
    return delegate;
  }

  private static OutputStreamManager getDefaultManager(final Target target, final boolean follow,
      final boolean direct, final Layout<? extends Serializable> layout) {

    OutputStream os = NullOutputStream.getInstance();
    String managerName = target.name() + '.' + follow + '.' + direct + "-" + COUNT.get();
    return OutputStreamManager.getManager(managerName, new FactoryData(os, managerName, layout),
        MANAGER_FACTORY);
  }

  private static OutputStreamManager getManager(final Target target, final boolean follow,
      final boolean direct, final Layout<? extends Serializable> layout) {
    OutputStream os = NullOutputStream.getInstance();
    String managerName = "null." + target.name() + '.' + follow + '.' + direct;
    return OutputStreamManager.getManager(managerName, new FactoryData(os, managerName, layout),
        MANAGER_FACTORY);
  }

  private static class FactoryData {
    private final OutputStream os;
    private final String name;
    private final Layout<? extends Serializable> layout;

    public FactoryData(final OutputStream os, final String type,
        final Layout<? extends Serializable> layout) {
      this.os = os;
      name = type;
      this.layout = layout;
    }
  }

  private static class AccessibleOutputStreamManager extends OutputStreamManager {

    protected AccessibleOutputStreamManager(final OutputStream os, final String streamName,
        final Layout<?> layout, final boolean writeHeader) {
      super(os, streamName, layout, writeHeader);
    }

    protected AccessibleOutputStreamManager(final OutputStream os, final String streamName,
        final Layout<?> layout,
        final boolean writeHeader, final int bufferSize) {
      super(os, streamName, layout, writeHeader, bufferSize);
    }
  }

  private static class GeodeConsoleManagerFactory implements
      ManagerFactory<OutputStreamManager, FactoryData> {

    @Override
    public OutputStreamManager createManager(final String name, final FactoryData data) {
      return new AccessibleOutputStreamManager(data.os, data.name, data.layout, true);
    }
  }
}
