package com.orange.config;

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

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.servicebroker.model.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;

import com.orange.model.PlanMetadata;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.beanutils.PropertyUtils;
import java.lang.reflect.InvocationTargetException;
import java.io.IOException;

@EnableGlobalMethodSecurity
@Configuration
public class CatalogConfig {
	@Value("#{ systemEnvironment['SERVICES_ID_NAME'] }")
	private String name;
	@Value("#{ systemEnvironment['SERVICES_ID_DESCRIPTION'] }")
	private String description = "";
	@Value("#{ systemEnvironment['SERVICES_ID_BINDEABLE'] ?: true}")
	private boolean bindable;
	@Value("#{ systemEnvironment['SERVICES_ID_TAGS'] }")
	private String tagstr;

	@Value("#{ systemEnvironment['SERVICES_ID_METADATA_DISPLAYNAME'] ?: systemEnvironment['SERVICES_ID_NAME']}")
	private String meta_displayname;
	@Value("#{ systemEnvironment['SERVICES_ID_METADATA_IMAGEURL'] ?: ''}")
	private String meta_imageurl;
	@Value("#{ systemEnvironment['SERVICES_ID_METADATA_SUPPORTURL'] ?: ''}")
	private String meta_supporturl;
	@Value("#{ systemEnvironment['SERVICES_ID_METADATA_DOCUMENTATIONURL'] ?: ''}")
	private String meta_documentationurl;
	@Value("#{ systemEnvironment['SERVICES_ID_METADATA_PROVIDERDISPLAYNAME'] ?: ''}")
	private String meta_providerdisplayname;
	@Value("#{ systemEnvironment['SERVICES_ID_METADATA_LONGDESCRIPTION'] ?: ''}")
	private String meta_longdescription;

	@Value("#{ systemEnvironment['PLAN_NAME'] ?: 'default' }")
	private String plan_name;
	@Value("#{ systemEnvironment['PLAN_DESCRIPTION'] ?: 'Default plan' }")
	private String plan_description;
	@Value("#{ systemEnvironment['PLAN_FREE'] ?: true}")
	private boolean plan_free;
	@Value("#{ systemEnvironment['PLAN_METADATA'] ?: '{}'}")
	private String plan_metadata_str;

	@Bean
	public Catalog catalog(){
		List<ServiceDefinition> serviceDefinitions = new ArrayList<ServiceDefinition>();
		String service_id = "000d5d66-e95b-4c19-beaf-064becbd3ada";

		Map<String, Object> service_metadata = new HashMap<String, Object>();
		service_metadata.put("displayName", meta_displayname);
		service_metadata.put("imageUrl", meta_imageurl);
		service_metadata.put("longDescription", meta_longdescription);
		service_metadata.put("providerDisplayName", meta_providerdisplayname);
		service_metadata.put("documentationUrl", meta_documentationurl);
		service_metadata.put("supportUrl", meta_supporturl);

		String plan_id = "101d240e-c36f-46e8-b35f-97d2f69bd185";
		List<String> tags = new ArrayList<String>();
		if (tagstr != null) {
			tags = Arrays.asList(tagstr.split(","));
		}
		ObjectMapper mapper = new ObjectMapper();
		Map<String, Object> plan_metadata = new HashMap<>();
		try {
			plan_metadata = PropertyUtils.describe(mapper.readValue(plan_metadata_str, PlanMetadata.class));
			plan_metadata.remove("class");
		} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException | IOException e) {
			e.printStackTrace();
		}
		Plan plan = new Plan(plan_id, plan_name, plan_description, plan_metadata, plan_free);
		ServiceDefinition service = new ServiceDefinition(service_id, name, description, bindable, false, Collections.singletonList(plan), tags, service_metadata, null, null);
		serviceDefinitions.add(service);
		Catalog catalog = new Catalog(serviceDefinitions);
		return catalog;
	}
}

@@ -2409,16 +2409,737 @@
 d3ada%22;%0A
+%09%09Map%3CString, Object%3E service_metadata = getServiceMetadata();%0A%09%09List%3CString%3E tags = new ArrayList%3CString%3E();%0A%09%09if (tagstr != null) %7B%0A%09%09%09tags = Arrays.asList(tagstr.split(%22,%22));%0A%09%09%7D%0A%0A%09%09String plan_id = %22101d240e-c36f-46e8-b35f-97d2f69bd185%22;%0A%09%09Map%3CString, Object%3E plan_metadata = getPlanMetadata();%0A%09%09Plan plan = new Plan(plan_id, plan_name, plan_description, plan_metadata, plan_free);%0A%09%09%0A%09%09ServiceDefinition service = new ServiceDefinition(service_id, name, description, bindable, false, Collections.singletonList(plan), tags, service_metadata, null, null);%0A%09%09serviceDefinitions.add(service);%0A%09%09Catalog catalog = new Catalog(serviceDefinitions);%0A%09%09return catalog;%0A%09%7D%0A%09%0A%09private Map%3CString, Object%3E getServiceMetadata()%7B
 %0A%09%09Map%3CS
@@ -3575,186 +3575,87 @@
 l);%0A
-%0A
 %09%09
-String plan_id = %22101d240e-c36f-46e8-b35f-97d2f69bd185%22;%0A%09%09List%3CString%3E tags = new ArrayList%3CString%3E();%0A%09%09if (tagstr != null) %7B%0A%09%09%09tags = Arrays.asList(tagstr.split(%22,%22));%0A%09%09%7D
+return service_metadata;%0A%09%7D%0A%09%0A%09private Map%3CString, Object%3E getPlanMetadata()%7B
 %0A%09%09O
@@ -4031,368 +4031,28 @@
 %7D%0A%09%09
-Plan plan = new Plan(plan_id, plan_name, plan_description, plan_metadata, plan_free);%0A%09%09ServiceDefinition service = new ServiceDefinition(service_id, name, description, bindable, false, Collections.singletonList(plan), tags, service_metadata, null, null);%0A%09%09serviceDefinitions.add(service);%0A%09%09Catalog catalog = new Catalog(serviceDefinitions);%0A%09%09return catalog
+return plan_metadata
 ;%0A%09%7D

restructure the class CatalogConfig, to move get metadata of service and plan into separated functions