content: /*
   * Copyright The OpenTelemetry Authors
   * SPDX-License-Identifier: Apache-2.0
   */
  
  package io.opentelemetry.instrumentation.runtimemetrics.java17;
  
  import static java.util.stream.Collectors.joining;
  import static java.util.stream.Collectors.toSet;
  
  import io.opentelemetry.sdk.OpenTelemetrySdk;
  import io.opentelemetry.sdk.metrics.SdkMeterProvider;
  import io.opentelemetry.sdk.metrics.data.MetricData;
  import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader;
  import java.io.IOException;
  import java.net.HttpURLConnection;
  import java.net.URL;
  import java.nio.file.Files;
  import java.nio.file.Path;
  import java.nio.file.Paths;
  import java.util.HashMap;
  import java.util.Map;
  import java.util.logging.Level;
  import java.util.logging.Logger;
  import java.util.regex.Pattern;
  
  /** Called from {@code ./gradlew generateDocs} to generate the markdown table in README.md. */
  public class GenerateDocs {
  
    private static final Logger logger = Logger.getLogger(GenerateDocs.class.getName());
  
    private static final String JFR_README_PATH_KEY = "jfr.readme.path";
    private static final String START = "<!-- generateDocsStart -->";
    private static final String END = "<!-- generateDocsEnd -->";
    private static final Pattern PATTERN = Pattern.compile(START + ".*" + END, Pattern.DOTALL);
  
    private GenerateDocs() {}
  
    public static void main(String[] args) throws Exception {
      // Suppress info level logs
      Logger.getLogger(RuntimeMetrics.class.getName()).setLevel(Level.WARNING);
  
      String jfrReadmePath = System.getProperty(JFR_README_PATH_KEY);
      if (jfrReadmePath == null) {
        throw new IllegalStateException(JFR_README_PATH_KEY + " is required");
      }
  
      logger.info("Generating JFR docs. Writing to " + jfrReadmePath);
      String markdownTable = generateMarkdownTable();
      logger.info("Markdown table: " + System.lineSeparator() + markdownTable);
      writeReadme(markdownTable, jfrReadmePath);
      logger.info("Done");
    }
  
    private static String generateMarkdownTable() throws InterruptedException {
      // Create new JfrTelemetry for each JfrFeature
      Map<JfrFeature, JfrTelemetryWithFeature> map = new HashMap<>();
      for (JfrFeature feature : JfrFeature.values()) {
        InMemoryMetricReader reader = InMemoryMetricReader.createDelta();
        OpenTelemetrySdk sdk =
            OpenTelemetrySdk.builder()
                .setMeterProvider(SdkMeterProvider.builder().registerMetricReader(reader).build())
                .build();
        map.put(
            feature,
            new JfrTelemetryWithFeature(
                RuntimeMetrics.builder(sdk).disableAllFeatures().enableFeature(feature).build(),
                sdk,
                reader));
      }
  
      // Exercise JVM to produce various JFR events
      System.gc();
      executeDummyNetworkRequest("https://opentelemetry.io");
      Thread.sleep(2000);
  
      // Build table, shut everything down
      StringBuilder table =
          new StringBuilder("| JfrFeature | Default Enabled | Metrics |")
              .append(System.lineSeparator())
              .append("|---|---|---|")
              .append(System.lineSeparator());
      for (JfrFeature feature : JfrFeature.values()) {
        JfrTelemetryWithFeature jfrTelemetryWithFeature = map.get(feature);
        String metricCol =
            jfrTelemetryWithFeature.reader.collectAllMetrics().stream()
                .map(MetricData::getName)
                .collect(toSet())
                .stream()
                .sorted()
                .map(s -> "`" + s + "`")
                .collect(joining(", "));
        table
            .append("| ")
            .append(feature.name())
            .append(" | ")
            .append(feature.isDefaultEnabled())
            .append(" | ")
            .append(metricCol)
            .append(" |")
            .append(System.lineSeparator());
        jfrTelemetryWithFeature.sdk.getSdkMeterProvider().close();
        jfrTelemetryWithFeature.jfrTelemetry.close();
      }
  
      return table.toString();
    }
  
    private static class JfrTelemetryWithFeature {
      private final RuntimeMetrics jfrTelemetry;
      private final OpenTelemetrySdk sdk;
      private final InMemoryMetricReader reader;
  
      private JfrTelemetryWithFeature(
          RuntimeMetrics jfrTelemetry, OpenTelemetrySdk sdk, InMemoryMetricReader reader) {
        this.jfrTelemetry = jfrTelemetry;
        this.sdk = sdk;
        this.reader = reader;
      }
    }
  
    private static void executeDummyNetworkRequest(String urlString) {
      try {
        URL url = new URL(urlString);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");
        connection.getResponseCode();
      } catch (IOException e) {
        throw new IllegalStateException("Failed to execute request", e);
      }
    }
  
    private static void writeReadme(String markdownTable, String jfrReadmePath) throws IOException {
      Path path = Paths.get(jfrReadmePath);
      String readmeContent = Files.readString(path);
      readmeContent =
          PATTERN
              .matcher(readmeContent)
              .replaceAll(
                  START
                      + System.lineSeparator()
                      + System.lineSeparator()
                      + markdownTable
                      + System.lineSeparator()
                      + END);
      Files.writeString(path, readmeContent);
    }
  }
  