package com.github.aureliano.evtbridge.core.doc;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.github.aureliano.evtbridge.common.exception.EventBridgeException;
import com.github.aureliano.evtbridge.core.SchemaTypes;
import com.github.aureliano.evtbridge.core.config.EventCollectorConfiguration;
import com.github.aureliano.evtbridge.core.config.InputConfigTypes;
import com.github.aureliano.evtbridge.core.config.OutputConfigTypes;
import com.github.aureliano.evtbridge.core.register.ApiServiceRegistrator;
import com.github.aureliano.evtbridge.core.schedule.ExecuteOnceAtSpecificTimeScheduler;
import com.github.aureliano.evtbridge.core.schedule.ExecutePeriodicallyAtSpecificTimeScheduler;
import com.github.aureliano.evtbridge.core.schedule.ExecutePeriodicallyScheduler;
import com.github.aureliano.evtbridge.core.schedule.SchedulerTypes;

public class MapSchemaBuilder extends SchemaBuilder<Map<String, Object>> {

	public MapSchemaBuilder() {}

	@Override
	public Map<String, Object> build(SchemaTypes schemaType) {
		switch (schemaType) {
		case ROOT:
			return this.buildSchema(EventCollectorConfiguration.class);
		case SCHEDULER:
			return this.buildSchedulerSchema();
		case INPUT:
			return this.buildInputSchema();
		case OUTPUT:
			return this.buildOutputSchema();
		default:
			throw new EventBridgeException("Unsupported schema type '" + schemaType + "'");
		}
	}
	
	@Override
	public Map<String, Object> build(SchedulerTypes schedulerType) {
		switch (schedulerType) {
		case EXECUTE_PERIODICALLY:
			return this.buildSchema(ExecutePeriodicallyScheduler.class);
		case EXECUTE_ONCE_AT_SPECIFIC_TIME:
			return this.buildSchema(ExecuteOnceAtSpecificTimeScheduler.class);
		case EXECUTE_PERIODICALLY_AT_SPECIFIC_TIME:
			return this.buildSchema(ExecutePeriodicallyAtSpecificTimeScheduler.class);
		default:
			throw new EventBridgeException("Unsupported scheduler type '" + schedulerType + "'");
		}
	}
	
	@Override
	public Map<String, Object> build(InputConfigTypes inputType) {
		ApiServiceRegistrator services = ApiServiceRegistrator.instance();
		
		switch (inputType) {
		case FILE:
			return null;
		default:
			throw new EventBridgeException("Unsupported input type '" + inputType + "'");
		}
	}

	private Map<String, Object> buildOutputSchema() {
		return this.buildAggregationSchema("Output configuration.", OutputConfigTypes.values());
	}

	private Map<String, Object> buildInputSchema() {
		return this.buildAggregationSchema("Input configuration.", InputConfigTypes.values());
	}

	private Map<String, Object> buildSchedulerSchema() {
		return this.buildAggregationSchema("Scheduling execution configuration.", SchedulerTypes.values());
	}

	private Map<String, Object> buildSchema(Class<?> configuration) {
		if (super.schema != null) {
			super.schema.clear();
		}
		
		super.configureSchemaHeader(configuration);
		super.configureSchemaProperties(configuration);
		
		return super.schema;
	}
	
	private Map<String, Object> buildAggregationSchema(String title, Object[] values) {
		if (super.schema != null) {
			super.schema.clear();
		}
		
		super.schema.put("$schema", "http://json-schema.org/draft-04/schema#");
		super.schema.put("title", title);
		super.schema.put("type", "object");
		
		List<Map<String, Object>> anyOf = new ArrayList<>();
		
		for (Object value : values) {
			Map<String, Object> refType = new HashMap<>();
			refType.put("$ref", value.toString().toLowerCase());
			anyOf.add(refType);
		}
		
		Map<String, Object> type = new HashMap<>();
		type.put("anyOf", anyOf);
		
		Map<String, Object> properties = new HashMap<>();
		properties.put("type", type);
		super.schema.put("properties", properties);
		
		return super.schema;
	}
}
@@ -351,24 +351,90 @@
 figuration;%0A
+import com.github.aureliano.evtbridge.core.config.IConfiguration;%0A
 import com.g
@@ -2125,225 +2125,50 @@
 %7B%0A%09%09
-ApiServiceRegistrator services = ApiServiceRegistrator.instance();%0A%09%09%0A%09%09switch (inputType) %7B%0A%09%09case FILE:%0A%09%09%09return null;%0A%09%09default:%0A%09%09%09throw new EventBridgeException(%22Unsupported input type '%22 + inputType + %22'%22);%0A%09%09%7D
+return this.buildSchema(inputType.name());
 %0A%09%7D%0A
@@ -2503,32 +2503,32 @@
 dulerSchema() %7B%0A
-
 %09%09return this.bu
@@ -2607,32 +2607,459 @@
 es.values());%0A%09%7D
+%0A%09%0A%09private Map%3CString, Object%3E buildSchema(String configurationId) %7B%0A%09%09ApiServiceRegistrator services = ApiServiceRegistrator.instance();%0A%09%09Class%3C? extends IConfiguration%3E configuration = services.getConfiguration(configurationId);%0A%09%09%0A%09%09if (configuration == null) %7B%0A%09%09%09throw new EventBridgeException(%22Could not find any registered configuration with id %22 + configurationId);%0A%09%09%7D%0A%09%09%0A%09%09return this.buildSchema(configuration);%0A%09%7D
 %0A%0A%09private Map%3CS

Build input schema.