// Copyright (C) 2020 The Android Open Source Project
//
// Licensed 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 com.google.gerrit.pgm.util;

import com.google.gerrit.util.logging.JsonLayout;
import com.google.gerrit.util.logging.JsonLogEntry;
import com.google.gson.annotations.SerializedName;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.spi.ThrowableInformation;

/** Layout for formatting error log events in the JSON format. */
public class ErrorLogJsonLayout extends JsonLayout {
  private final Boolean enableReverseDnsLookup;

  public ErrorLogJsonLayout(Boolean enableDnsReverseLookup) {
    super();
    this.enableReverseDnsLookup = enableDnsReverseLookup;
  }

  @Override
  public JsonLogEntry toJsonLogEntry(LoggingEvent event) {
    return new ErrorJsonLogEntry(event);
  }

  @SuppressWarnings("unused")
  private class ErrorJsonLogEntry extends JsonLogEntry {
    /** Timestamp of when the log entry was created. */
    @SerializedName("@timestamp")
    public final String timestamp;

    /** Hostname of the machine running Gerrit. */
    public final String sourceHost;
    /** Logged message. */
    public final String message;
    /** File containing the code creating the log entry. */
    public final String file;
    /** Line number of code creating the log entry. */
    public final String lineNumber;

    /** Class from which the log entry was created. */
    @SerializedName("class")
    public final String clazz;

    /** Method from which the log entry was created. */
    public final String method;
    /** Name of the logger creating the log entry. */
    public final String loggerName;

    /** Mapped diagnostic context. */
    @SuppressWarnings("rawtypes")
    public final Map mdc;

    /** Nested diagnostic context. */
    public final String ndc;
    /** Logging level/severity. */
    public final String level;
    /** Thread executing the code creating the log entry. */
    public final String threadName;

    /** Version of log format. */
    @SerializedName("@version")
    public final int version = 2;

    /**
     * Map containing information of a logged exception. It contains the following key-value pairs:
     * exception_class: Which class threw the exception exception_method: Which method threw the
     * exception stacktrace: The exception stacktrace
     */
    public Map<String, String> exception;

    public ErrorJsonLogEntry(LoggingEvent event) {
      this.timestamp = timestampFormatter.format(event.getTimeStamp());
      this.sourceHost = getSourceHost(enableReverseDnsLookup);
      this.message = event.getRenderedMessage();
      this.file = event.getLocationInformation().getFileName();
      this.lineNumber = event.getLocationInformation().getLineNumber();
      this.clazz = event.getLocationInformation().getClassName();
      this.method = event.getLocationInformation().getMethodName();
      this.loggerName = event.getLoggerName();
      this.mdc = event.getProperties();
      this.ndc = event.getNDC();
      this.level = event.getLevel().toString();
      this.threadName = event.getThreadName();
      if (event.getThrowableInformation() != null) {
        this.exception = getException(event.getThrowableInformation());
      }
    }

    private String getSourceHost(Boolean enableReverseDnsLookup) {
      InetAddress in;
      try {
        in = InetAddress.getLocalHost();
        if (Boolean.TRUE.equals(enableReverseDnsLookup)) {
          return in.getCanonicalHostName();
        }
        return in.getHostAddress();
      } catch (UnknownHostException e) {
        return "unknown-host";
      }
    }

    private Map<String, String> getException(ThrowableInformation throwable) {
      HashMap<String, String> exceptionInformation = new HashMap<>();

      String throwableName = throwable.getThrowable().getClass().getCanonicalName();
      if (throwableName != null) {
        exceptionInformation.put("exception_class", throwableName);
      }

      String throwableMessage = throwable.getThrowable().getMessage();
      if (throwableMessage != null) {
        exceptionInformation.put("exception_message", throwableMessage);
      }

      String[] stackTrace = throwable.getThrowableStrRep();
      if (stackTrace != null) {
        exceptionInformation.put("stacktrace", String.join("\n", stackTrace));
      }
      return exceptionInformation;
    }
  }
}
