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

import java.io.Serializable;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

import org.apache.commons.lang3.exception.ExceptionUtils;
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.AbstractAppender;
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.geode.alerting.internal.AlertingSessionRegistryProvider;
import org.apache.geode.alerting.internal.NullAlertingService;
import org.apache.geode.alerting.internal.api.AlertingService;
import org.apache.geode.alerting.internal.log4j.AlertLevelConverter;
import org.apache.geode.alerting.internal.spi.AlertLevel;
import org.apache.geode.alerting.internal.spi.AlertingAction;
import org.apache.geode.alerting.internal.spi.AlertingSessionListener;
import org.apache.geode.alerting.internal.spi.AlertingSessionRegistry;
import org.apache.geode.annotations.VisibleForTesting;
import org.apache.geode.logging.log4j.internal.impl.DebuggableAppender;
import org.apache.geode.logging.log4j.internal.impl.PausableAppender;

@Plugin(name = AlertAppender.PLUGIN_NAME, category = Core.CATEGORY_NAME,
    elementType = Appender.ELEMENT_TYPE, printObject = true)
@SuppressWarnings("unused")
public class AlertAppender extends AbstractAppender
    implements PausableAppender, DebuggableAppender, AlertingSessionListener {

  static final String PLUGIN_NAME = "GeodeAlert";

  private static final boolean START_PAUSED_BY_DEFAULT = true;

  private final AtomicReference<AlertingService> alertingServiceRef =
      new AtomicReference<>(NullAlertingService.get());

  private final boolean debug;
  private final List<LogEvent> events;
  private final AlertingSessionRegistry alertingSessionRegistry;

  private volatile boolean paused;

  @VisibleForTesting
  AlertAppender(final String name,
      final Layout<? extends Serializable> layout,
      final Filter filter) {
    this(name, layout, filter, START_PAUSED_BY_DEFAULT, false,
        AlertingSessionRegistryProvider.get());
  }

  private AlertAppender(final String name,
      final Layout<? extends Serializable> layout,
      final Filter filter,
      final boolean startPaused,
      final boolean debug,
      final AlertingSessionRegistry alertingSessionRegistry) {
    super(name, filter, layout);
    this.debug = debug;
    if (debug) {
      events = Collections.synchronizedList(new ArrayList<>());
    } else {
      events = Collections.emptyList();
    }
    paused = true;
    this.alertingSessionRegistry = alertingSessionRegistry;
  }

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

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

    @PluginBuilderAttribute
    private boolean debug;

    @PluginBuilderAttribute
    private boolean startPaused = START_PAUSED_BY_DEFAULT;

    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 AlertAppender build() {
      Layout<? extends Serializable> layout = getOrCreateLayout();
      return new AlertAppender(getName(), layout, getFilter(), startPaused, debug,
          AlertingSessionRegistryProvider.get());
    }
  }

  @Override
  public void append(final LogEvent event) {
    LOGGER.trace("Handling append of {} in {}.", event, this);
    if (isPaused()) {
      LOGGER.trace("Skipping append of {} because {} is paused.", event, this);
      return;
    }
    if (!AlertLevelConverter.hasAlertLevel(event.getLevel())) {
      LOGGER.trace("Skipping append of {} because level is {}.", event, event.getLevel());
      return;
    }
    if (AlertingAction.isThreadAlerting()) {
      // If already appending then don't send to avoid infinite recursion
      LOGGER.trace("Skipping append of {} because {} is alerting.", event, Thread.currentThread());
      return;
    }
    AlertingAction.execute(() -> doAppend(event));
  }

  private void doAppend(final LogEvent event) {
    AlertingService alertingService = getAlertingService();
    if (alertingService.hasAlertListeners()) {
      sendAlerts(event);
    } else {
      LOGGER.trace("Skipping alert messaging for {} because listeners is empty.", event);
    }
    if (debug) {
      events.add(event);
    }
  }

  private void sendAlerts(final LogEvent event) {
    AlertingService alertingService = getAlertingService();

    AlertLevel alertLevel = AlertLevelConverter.fromLevel(event.getLevel());
    Instant instant = Instant.ofEpochMilli(event.getTimeMillis());
    String threadName = event.getThreadName();
    long threadId = Thread.currentThread().getId();
    String formattedMessage = event.getMessage().getFormattedMessage();
    String stackTrace = getStackTrace(event);

    alertingService.sendAlerts(alertLevel, instant, threadName, threadId, formattedMessage,
        stackTrace);
  }

  private String getStackTrace(final LogEvent event) {
    return event.getThrown() == null ? null : ExceptionUtils.getStackTrace(event.getThrown());
  }

  @Override
  public void start() {
    LOGGER.info("Starting {}.", this);
    LOGGER.debug("Adding {} to {}.", this, alertingSessionRegistry);
    alertingSessionRegistry.addAlertingSessionListener(this);
    super.start();
  }

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

    // stop LogEvents from coming to this appender
    super.stop();

    alertingSessionRegistry.removeAlertingSessionListener(this);

    LOGGER.info("{} has stopped.", this);
  }

  @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 Collections.unmodifiableList(events);
  }

  @Override
  public synchronized void createSession(final AlertingService alertingService) {
    LOGGER.info("Creating session in {} with {}.", this, alertingService);
    setAlertingService(alertingService);
  }

  @Override
  public synchronized void startSession() {
    LOGGER.info("Starting session in {}.", this);
    resume();
  }

  @Override
  public synchronized void stopSession() {
    LOGGER.info("Stopping session in {}.", this);
    pause();
    setAlertingService(NullAlertingService.get());
  }

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

  @VisibleForTesting
  void setAlertingService(final AlertingService alertingService) {
    alertingServiceRef.set(alertingService);
  }

  @VisibleForTesting
  AlertingService getAlertingService() {
    return alertingServiceRef.get();
  }
}
