package org.stagemonitor;

import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.stagemonitor.configuration.ConfigurationOption;
import org.stagemonitor.configuration.ConfigurationRegistry;
import org.stagemonitor.core.StagemonitorPlugin;
import org.stagemonitor.util.StringUtils;

import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Map;

public class ConfigurationOptionsMarkdownExporter {

	private ConfigurationOptionsMarkdownExporter() {
	}

	public static void main(String[] args) throws IOException {
		final ConfigurationRegistry configurationRegistry = new ConfigurationRegistry(StagemonitorPlugin.class);
		System.out.println(getMarkdown(configurationRegistry));
	}

	private static String getMarkdown(ConfigurationRegistry configurationRegistry) {
		StringBuilder markdown = new StringBuilder();
		final Map<String, List<ConfigurationOption<?>>> configurationOptionsByPlugin = configurationRegistry.getConfigurationOptionsByCategory();

		MultiValueMap<String, ConfigurationOption<?>> configurationOptionsByTags = new LinkedMultiValueMap<>();
		configurationOptionsByPlugin.values()
				.stream()
				.flatMap(Collection::stream)
				.filter(opt -> !opt.getTags().isEmpty())
				.forEach(opt -> opt.getTags()
						.forEach(tag -> configurationOptionsByTags.add(tag, opt)));


		markdown.append("# Overview\n");
		markdown.append("## All Plugins\n");
		for (String plugin : configurationOptionsByPlugin.keySet()) {
			markdown.append("* ").append(linkToHeadline(plugin)).append('\n');
		}
		markdown.append("\n");
		markdown.append("## Available Tags\n");
		for (String tag : configurationOptionsByTags.keySet()) {
			markdown.append("`").append(tag).append("` ");
		}
		markdown.append("\n");

		markdown.append("# Options by Plugin\n");
		for (Map.Entry<String, List<ConfigurationOption<?>>> entry : configurationOptionsByPlugin.entrySet()) {
			final String pluginName = entry.getKey();
			markdown.append("* ").append(linkToHeadline(pluginName)).append('\n');
			for (ConfigurationOption<?> option : entry.getValue()) {
				markdown.append("  * ").append(linkToHeadline(option.getLabel())).append('\n');
			}
		}
		markdown.append("\n");

		markdown.append("# Options by Tag\n");
		markdown.append("\n");
		for (Map.Entry<String, List<ConfigurationOption<?>>> entry : configurationOptionsByTags.entrySet()) {
			markdown.append("* `").append(entry.getKey()).append("` \n");
			for (ConfigurationOption<?> option : entry.getValue()) {
				markdown.append("  * ").append(linkToHeadline(option.getLabel())).append('\n');
			}}
		markdown.append("\n");

		for (Map.Entry<String, List<ConfigurationOption<?>>> entry : configurationOptionsByPlugin.entrySet()) {
			markdown.append("# ").append(entry.getKey()).append("\n\n");
			for (ConfigurationOption<?> configurationOption : entry.getValue()) {
				markdown.append("## ").append(configurationOption.getLabel()).append("\n\n");
				if (configurationOption.getDescription() != null) {
					markdown.append(configurationOption.getDescription()).append("\n\n");
				}
				markdown.append("Key: `").append(configurationOption.getKey()).append("`\n\n");
				markdown.append("Default Value: ");
				final String defaultValue = configurationOption.getDefaultValueAsString();
				if (defaultValue == null) {
					markdown.append("`null`\n\n");
				} else if (!defaultValue.contains("\n")) {
					markdown.append('`').append(defaultValue).append("`\n\n");
				} else {
					markdown.append("\n\n```\n").append(defaultValue).append("\n```\n\n");
				}
				if (!configurationOption.getTags().isEmpty()) {
					markdown.append("Tags: ");
					for (String tag : configurationOption.getTags()) {
						markdown.append('`').append(tag).append("` ");
					}
					markdown.append("\n\n");
				}
			}
			markdown.append("***\n\n");
		}
		return markdown.toString();
	}

	private static String linkToHeadline(String headline) {
		return "[" + headline + "](#" + StringUtils.slugify(headline) + ')';
	}
}

@@ -433,16 +433,68 @@
 til.Map;
+%0Aimport java.util.TreeMap;%0Aimport java.util.TreeSet;
 %0A%0Apublic
@@ -1035,16 +1035,30 @@
 lugin = 
+new TreeMap%3C%3E(
 configur
@@ -1106,16 +1106,17 @@
 tegory()
+)
 ;%0A%0A%09%09Mul
@@ -1547,16 +1547,30 @@
 lugin : 
+new TreeSet%3C%3E(
 configur
@@ -1591,32 +1591,33 @@
 Plugin.keySet())
+)
  %7B%0A%09%09%09markdown.a
@@ -1756,32 +1756,46 @@
 r (String tag : 
+new TreeSet%3C%3E(
 configurationOpt
@@ -1810,24 +1810,25 @@
 gs.keySet())
+)
  %7B%0A%09%09%09markdo

Improve configuration markdown export