package ru.simplex_software.wicket_springdata;

import org.apache.wicket.util.convert.ConversionException;
import org.apache.wicket.util.convert.IConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;

public class WicketEnumConverter implements IConverter {
    private static final Logger LOG = LoggerFactory.getLogger(WicketEnumConverter.class);

    private static final Map<Class<? extends Enum>, Properties> PROPERTIES_MAP = new HashMap<>();
    private Class<? extends Enum> enumClass;

    /**
     * Enum in Constructor.
     */
    public WicketEnumConverter(Class<? extends Enum> enumClass) {
        this.enumClass = enumClass;
    }

    @Override
    public Enum convertToObject(String value, Locale locale) throws ConversionException {
        Properties props = null;
        try {
            props = getProperties();
        } catch (IOException e) {
            LOG.debug("Check Properties of " + value);
        }
        for (Map.Entry e : props.entrySet()) {
            if (e.getValue().equals(value)) {
                String key = (String) e.getKey();
                return Enum.valueOf(enumClass, key);
            }
        }
        return null;
    }

    @Override
    public String convertToString(Object value, Locale locale) {
        Enum statusValue = (Enum) value;
        Properties props;
        try {
            props = getProperties();
        } catch (IOException e) {
            LOG.error("Check Properties of " + value.getClass().getCanonicalName());
            throw new RuntimeException(e);
        }
        String key = statusValue.name();
        return props.getProperty(key);
    }

    /**
     * Load properties from file.
     */
    private Properties getProperties() throws IOException {
        Properties properties = PROPERTIES_MAP.get(enumClass);
        if (properties != null) {
            return properties;
        }
        properties = new Properties();
        synchronized (PROPERTIES_MAP) {
            String fileName = "translations/" + enumClass.getCanonicalName() + ".properties";
            InputStream stream = enumClass.getClassLoader().getResourceAsStream(fileName);
            if (stream == null) { // File not found.
                LOG.debug("Не удалось найти файл свойств для " + enumClass.getName());
                throw new FileNotFoundException("Не удалось найти файл свойств для " + enumClass.getName());
            }
            properties.load(stream);
            PROPERTIES_MAP.put(enumClass, properties);
            return properties;
        }
    }
}
