package com.airlock.iam.plugin.framework.infrastructure.xstream;

import com.airlock.iam.plugin.framework.domain.model.property.Property;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import java.util.Optional;

abstract class AbstractPropertyConverter<T extends Property> implements Converter {
   private static final String NAME_ATTR = "name";
   private static final String CONTEXT_ATTR = "context";
   private static final String ENVID_ATTR = "envid";
   private static final String VAR_ATTR = "var";

   public final boolean canConvert(Class type) {
      return this.getPropertyClass().equals(type);
   }

   protected abstract Class<T> getPropertyClass();

   public final void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
      T property = this.getPropertyClass().cast(source);
      writer.startNode(this.tagName());
      XStreamHelper.forcefullyWriteAttribute(writer, "name", property.getName());
      XStreamHelper.writeAttributeIfValueIsPresent(writer, "envid", property.getEnvId());
      XStreamHelper.writeAttributeIfValueIsPresent(writer, "context", property.getContext());
      XStreamHelper.writeAttributeIfValueIsPresent(writer, "var", property.getVariable());
      this.marshalCustomAttributes(property, writer, context);
      writer.endNode();
   }

   protected abstract void marshalCustomAttributes(T var1, HierarchicalStreamWriter var2, MarshallingContext var3);

   protected abstract T createNewProperty(String var1, Optional<String> var2, Optional<String> var3, Optional<String> var4);

   public final Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext unmarshallingContext) {
      XStreamHelper.ensureInNode(this.tagName(), reader);
      String name = XStreamHelper.readMandatoryAttribute(reader, "name");
      Optional<String> envid = XStreamHelper.readOptionalAttribute(reader, "envid");
      Optional<String> context = XStreamHelper.readOptionalAttribute(reader, "context");
      Optional<String> variable = XStreamHelper.readOptionalAttribute(reader, "var");
      T property = this.createNewProperty(name, envid, context, variable);
      this.unmarshalCustomAttributes(property, reader, unmarshallingContext);
      return property;
   }

   protected abstract String tagName();

   protected abstract void unmarshalCustomAttributes(T var1, HierarchicalStreamReader var2, UnmarshallingContext var3);
}
