package com.persagy.adm.diagram.core.util;

import com.google.gson.*;
import com.persagy.adm.diagram.core.model.EquipmentNode;
import com.persagy.adm.diagram.core.model.Label;
import com.persagy.adm.diagram.core.model.base.Container;
import com.persagy.adm.diagram.core.model.base.IComponent;
import com.persagy.adm.diagram.core.model.logic.AndFilter;
import com.persagy.adm.diagram.core.model.logic.DataFilter;
import com.persagy.adm.diagram.core.model.logic.MatchFilter;
import com.persagy.adm.diagram.core.model.logic.OrFilter;
import com.persagy.adm.diagram.core.model.virtual.PackNode;
import org.springframework.stereotype.Component;

import java.lang.reflect.Type;

/**
 * gson解析和输出工具
 * @author zhaoyk
 */
@Component
public class GsonUtil {

	private Gson gson;

	private Gson formattedGson;

	public GsonUtil(){
		GsonBuilder gsonBuilder = new GsonBuilder().excludeFieldsWithoutExposeAnnotation();
		gsonBuilder.registerTypeAdapter(IComponent.class, new CompAdapter());
		gsonBuilder.registerTypeAdapter(DataFilter.class, new FilterAdapter());
		gson = gsonBuilder.create();

		formattedGson = new GsonBuilder().setPrettyPrinting().create();
	}

	public Gson gson(){
		return gson;
	}

	public Gson formattedGson(){
		return formattedGson;
	}


	class CompAdapter implements JsonDeserializer<IComponent>, JsonSerializer<IComponent> {

		@Override
		public IComponent deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
			Class<? extends IComponent> target = Container.class;
			if(Container.TYPE.equals(jsonElement.getAsJsonObject().get("compType")))
				target = Container.class;
			else if(EquipmentNode.TYPE.equals(jsonElement.getAsJsonObject().get("compType")))
				target = EquipmentNode.class;
			else if(PackNode.TYPE.equals(jsonElement.getAsJsonObject().get("compType")))
				target = PackNode.class;
			else if(Label.TYPE.equals(jsonElement.getAsJsonObject().get("compType")))
				target = Label.class;
			else {
				//TODO 其他类型
			}
			return gson.fromJson(jsonElement, target);
		}

		@Override
		public JsonElement serialize(IComponent iComponent, Type type, JsonSerializationContext jsonSerializationContext) {
			return gson.toJsonTree(iComponent, iComponent.getClass());
		}

	}

	class FilterAdapter implements JsonDeserializer<DataFilter>, JsonSerializer<DataFilter> {

		@Override
		public DataFilter deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
			Class<? extends DataFilter> target = null;
			int fType = jsonElement.getAsJsonObject().get("type").getAsInt();
			if(fType == DataFilter.TYPE_MATCH)
				target = MatchFilter.class;
			else if(fType == AndFilter.TYPE_AND)
				target = AndFilter.class;
			else if(fType == OrFilter.TYPE_OR)
				target = OrFilter.class;
			else {
				//TODO 其他类型
			}
			return gson.fromJson(jsonElement, target);
		}

		@Override
		public JsonElement serialize(DataFilter filter, Type type, JsonSerializationContext jsonSerializationContext) {
			return gson.toJsonTree(filter, filter.getClass());
		}

	}
}
