/*
 * Copyright (c) 2004-2017, by Alex Leigh.
 * All rights reserved.
 *
 * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE
 * The copyright notice above does not evidence any
 * actual or intended publication of such source code.
 */

package leigh.eo;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Serializable;
import java.math.BigDecimal;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.time.Instant;
import java.util.Locale;
import java.util.UUID;

/**
 * Field datatypes which are primarily used to hint to end-user interfaces as to the best
 * way to display the field. They should not be confused with the actual data-type of a given
 * field. For example, UUID fields typically would use the string field type.
 *
 * @author Alex Leigh
 */
public enum EODataType {
    string, password, instant, hyperlink, loop, bool, object, uuid, locale,
    ipv4, ipv6, number;

    private static final Logger logger = LoggerFactory.getLogger(EODataType.class);

    /**
     * Return the name of the method which would be used on a DAO to access a field of the given type.
     *
     * @param type
     * @return
     */
    public static String getAccessor(final EODataType type) {
        if (type == null) {
            logger.error("getAccessor(): null type provided. Defaulting to getValueString()");
            return "getValueString";
        }

        logger.debug("Type matching for: {}", type);

        switch (type) {
            case string:
            case password:
            case hyperlink:
                return "getValueString";
            case instant:
                return "getValueInstant";
            case loop:
                return "getValueLoop";
            case bool:
                return "getValueBoolean";
            case object:
                return "getValue";
            case uuid:
                return "getValueUUID";
            case locale:
                return "getValueLocale";
            case ipv4:
                return "getInet4Address";
            case ipv6:
                return "getInet6Address";
            case number:
                return "getNumber";
        }
        throw new IllegalArgumentException("Unrecognized type");
    }

    /**
     * Return the Java type which can be used to store the given value from the EO. This type is the same
     * as would be assigned to a getter() for the value in a DAO.
     */
    public static Class getType(EODataType type) {
        if (type == null) {
            logger.error("getType(): null type provided. Defaulting to string.");
            type = EODataType.string;
        }

        logger.debug("Type matching for: {}", type);

        switch (type) {
            case string:
            case password:
            case hyperlink:
                return String.class;
            case instant:
                return Instant.class;
            case loop:
                return EOLoop.class;
            case bool:
                return Boolean.class;
            case object:
                return Serializable.class;
            case uuid:
                return UUID.class;
            case locale:
                return Locale.class;
            case ipv4:
                return Inet4Address.class;
            case ipv6:
                return Inet6Address.class;
            case number:
                return BigDecimal.class;
        }
        throw new IllegalArgumentException("Unrecognized type");
    }
}
