// SPDX-FileCopyrightText: © 2021 Matthias Andreas Benkard <code@mail.matthias.benkard.de>
//
// SPDX-License-Identifier: LGPL-3.0-or-later

package eu.mulk.quarkus.googlecloud.jsonlogging;

import io.smallrye.common.constraint.Nullable;
import jakarta.json.JsonObject;
import jakarta.json.JsonObjectBuilder;
import jakarta.json.spi.JsonProvider;
import java.time.Instant;
import java.util.List;
import java.util.Map;

/**
 * A JSON log entry compatible with Google Cloud Logging.
 *
 * <p>Roughly (but not quite) corresponds to Google Cloud Logging's <a
 * href="https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry">LogEntry</a>
 * structure.
 *
 * <p>A few of the fields are <a href="https://cloud.google.com/logging/docs/structured-logging">
 * treated specially</a> by the fluentd instance running in Google Kubernetes Engine. All other
 * fields end up in the jsonPayload field on the Google Cloud Logging side.
 */
final class LogEntry {

  private final String message;
  private final String severity;
  private final Timestamp timestamp;
  @Nullable private final String trace;
  @Nullable private final String spanId;
  @Nullable private final SourceLocation sourceLocation;
  private final Map<String, String> labels;
  private final List<StructuredParameter> parameters;
  private final Map<String, String> mappedDiagnosticContext;
  @Nullable private final String nestedDiagnosticContext;
  @Nullable private final String type;

  LogEntry(
      String message,
      String severity,
      Timestamp timestamp,
      @Nullable String trace,
      @Nullable String spanId,
      @Nullable SourceLocation sourceLocation,
      Map<String, String> labels,
      List<StructuredParameter> parameters,
      Map<String, String> mappedDiagnosticContext,
      @Nullable String nestedDiagnosticContext,
      @Nullable String type) {
    this.message = message;
    this.severity = severity;
    this.timestamp = timestamp;
    this.trace = trace;
    this.spanId = spanId;
    this.sourceLocation = sourceLocation;
    this.labels = labels;
    this.parameters = parameters;
    this.mappedDiagnosticContext = mappedDiagnosticContext;
    this.nestedDiagnosticContext = nestedDiagnosticContext;
    this.type = type;
  }

  static final class SourceLocation {

    @Nullable private final String file;
    @Nullable private final String line;
    @Nullable private final String function;

    SourceLocation(@Nullable String file, @Nullable String line, @Nullable String function) {
      this.file = file;
      this.line = line;
      this.function = function;
    }

    JsonObject json(JsonProvider json) {
      var b = json.createObjectBuilder();

      if (file != null) {
        b.add("file", file);
      }

      if (line != null) {
        b.add("line", line);
      }

      if (function != null) {
        b.add("function", function);
      }

      return b.build();
    }
  }

  static final class Timestamp {

    private final long seconds;
    private final int nanos;

    Timestamp(long seconds, int nanos) {
      this.seconds = seconds;
      this.nanos = nanos;
    }

    Timestamp(Instant t) {
      this(t.getEpochSecond(), t.getNano());
    }

    JsonObject json(JsonProvider json) {
      return json.createObjectBuilder().add("seconds", seconds).add("nanos", nanos).build();
    }
  }

  JsonObjectBuilder json(JsonProvider json) {
    var b = json.createObjectBuilder();

    if (trace != null) {
      b.add("logging.googleapis.com/trace", trace);
    }

    if (spanId != null) {
      b.add("logging.googleapis.com/spanId", spanId);
    }

    if (nestedDiagnosticContext != null && !nestedDiagnosticContext.isEmpty()) {
      b.add("nestedDiagnosticContext", nestedDiagnosticContext);
    }

    if (!labels.isEmpty()) {
      b.add("logging.googleapis.com/labels", jsonOfStringMap(json, labels));
    }

    if (type != null) {
      b.add("@type", type);
    }

    b.add("message", message).add("severity", severity).add("timestamp", timestamp.json(json));

    if (sourceLocation != null) {
      b.add("logging.googleapis.com/sourceLocation", sourceLocation.json(json));
    }

    return b.addAll(jsonOfStringMap(json, mappedDiagnosticContext))
        .addAll(jsonOfParameterMap(json, parameters));
  }

  private JsonObjectBuilder jsonOfStringMap(JsonProvider json, Map<String, String> stringMap) {
    return stringMap.entrySet().stream()
        .reduce(
            json.createObjectBuilder(),
            (acc, x) -> acc.add(x.getKey(), x.getValue()),
            JsonObjectBuilder::addAll);
  }

  private JsonObjectBuilder jsonOfParameterMap(
      JsonProvider json, List<StructuredParameter> parameters) {
    return parameters.stream()
        .reduce(
            json.createObjectBuilder(),
            (acc, p) -> acc.addAll(p.json()),
            JsonObjectBuilder::addAll);
  }
}
