/*
 * [Rodents.java]
 *
 * Summary: Demonstrate how to define multiple aliases per enum constant with fast HashMap lookup.
 *
 * Copyright: (c) 2009-2017 Roedy Green, Canadian Mind Products, http://mindprod.com
 *
 * Licence: This software may be copied and used freely for any purpose but military.
 *          http://mindprod.com/contact/nonmil.html
 *
 * Requires: JDK 1.8+
 *
 * Created with: JetBrains IntelliJ IDEA IDE http://www.jetbrains.com/idea/
 *
 * Version History:
 *  1.0 2009-01-01 initial version
 */
package com.mindprod.example;

import java.util.HashMap;
import java.util.Map;

import static java.lang.System.*;

/**
 * Demonstrate how to define multiple aliases per enum constant with fast HashMap lookup.
 * <p/>
 * Define some rodents.  Demonstrate use of trick using statics.
 * Show how to define multiple aliases per constants with
 * fast HashMap lookup.
 *
 * @author Roedy Green, Canadian Mind Products
 * @version 1.0 2009-01-01 initial version
 * @since 2009-01-01
 */
@SuppressWarnings( { "UnusedDeclaration", "WeakerAccess" } )
public enum Rodents
    {
        /**
         * Canadian dam builder.
         */
        BEAVER( "castor" ),
        /**
         * rodent
         */
        RABBIT( "hare", "bunny" ),
        /**
         * South American water creature.
         */
        CAPYBARA( "water pig", "capibara"/* do not correct spelling */ );

    /**
     * size of hashmap to lookup aliases. Leave 25%+ extra space for speed
     */
    private static final int HASHMAPSIZE = 21;

    /**
     * constructor Work around for being unable to access statics in the enum constructor. Put the static in another
     * class.
     *
     * @param aliases 0..n aliases
     */
    @SuppressWarnings( { "SameParameterValue" } )
    Rodents( String... aliases )
        {
        Aliases.map.put( this.name().trim().toLowerCase(), this );
        for ( String alias : aliases )
            {
            Aliases.map.put( alias.trim().toLowerCase(), this );
            }
        }

    /**
     * Rodents Test harness
     *
     * @param args not used
     */
    @SuppressWarnings( { "UnusedParameters" } )
    public static void main( String[] args )
        {
        out.println( valueOfAlias( "hare" ) );
        out.println( valueOfAlias( "rabbit" ) );
        }

    /**
     * Convert name to corresponding enum constant.
     *
     * @param alias name or alternate name.
     *
     * @return corresponding enum constant.
     */
    @SuppressWarnings( { "SameParameterValue", "WeakerAccess" } )
    public static Rodents valueOfAlias( String alias )
        {
        Rodents constant = Aliases.map.get( alias.trim().toLowerCase() );
        if ( constant == null )
            {
            throw new IllegalArgumentException( "undefined constant for: "
                                                + alias );
            }
        return constant;
        }

    /**
     * map of aliases to enum constants
     */
    private static final class Aliases
        {
        /**
         * map from name no enum constant
         */
        static final Map<String, Rodents> map =
                new HashMap<>( HASHMAPSIZE );
        }
    }