package org.etsi.mts.tdl.openapi.generator.ui.handlers;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import org.openapitools.codegen.CodegenConfig;
import org.openapitools.codegen.CodegenConfigLoader;
import org.openapitools.codegen.OpenAPIGenerator;
import org.openapitools.codegen.meta.GeneratorMetadata;
import org.openapitools.codegen.utils.ModelUtils;

import io.swagger.parser.OpenAPIParser;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.parser.core.models.ParseOptions;

public class OpenAPIGeneratorLauncher {
	
	public static void main(String[] args) {
//		launch(input, target);
		listGenerators();
//		parse(input);
	}
	
	public static List<String> listGenerators() {
        List<CodegenConfig> generators = new ArrayList<>();
        List<String> generatorNames = new ArrayList<>();
		for (CodegenConfig codegenConfig : CodegenConfigLoader.getAll()) {
            GeneratorMetadata meta = codegenConfig.getGeneratorMetadata();
            if (meta != null) {
                generators.add(codegenConfig);
                generatorNames.add(codegenConfig.getName());
            }
        }
		return generatorNames;
	}

	public static void launch(String input, String target) {
		launch(input, null, target, null, true);
	}

	public static void launch(File input, File config, String target) {
		launch(input.getAbsolutePath(), config.getAbsolutePath(), target, null, true);
	}
	
	public static void launch(String input, String config, String target, String output, boolean skipValidation) {
		if (output == null) {
			String inputFolder = new File(input).getParentFile().getAbsolutePath();
			output = inputFolder+"/generated/"+target+"/";
			new File(output).mkdirs();
		}

		input = input.replaceAll("\\\\", "/");
		List<String> args = new ArrayList<String>(
				Arrays.asList(new String[] { "generate", "-g", target, "-i", input, "-o", output }));
		
		if (config != null) {
			args.add("-c");
			args.add(config);
		}
		
		if (skipValidation) {
			args.add("--skip-validate-spec");
		}
		OpenAPIGenerator.main(args.toArray(new String[args.size()]));
	}

	public static void validate(String input) {
		//TODO: adapt from source so that it does not exit or run in a separate process?
		OpenAPIGenerator.main(new String[] {"validate", "-i", input});
	}
	
	public static void parse(String input) {
		System.out.println("Parsing "+input);
		OpenAPI openAPI = new OpenAPIParser().readLocation(input, null, new ParseOptions()).getOpenAPI();
		Components components = openAPI.getComponents();
		Map<String, Schema> schemas = components.getSchemas();
		ArraySchema object = (ArraySchema) schemas.get("Library").getProperties().get("books");
		System.out.println(object.getItems().get$ref());
//		System.out.println(schemas.get("Library").getName());
		System.out.println("MU:"+ModelUtils.getReferencedSchema(openAPI, object.getItems()));
		schemas.forEach((k,v) -> System.out.println(k));
        // Invoke helper function to get the original swagger version.
        // See https://github.com/swagger-api/swagger-parser/pull/1374
        // Also see https://github.com/swagger-api/swagger-parser/issues/1369.
        ModelUtils.getOpenApiVersion(openAPI, input, null);
     
	}

}
