package de.visone.crawl.sys;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

/**
 * Data class for accessing the list of user agents.
 * 
 * @author matthias
 */
public final class UserAgents {
    private UserAgents() {
    }

    private static final Logger LOGGER = Logger.getLogger(UserAgents.class);

    private static final Map<String, String> USER_AGENTS = new HashMap<String, String>();
    private static final List<String> USER_AGENT_NAMES = new ArrayList<String>();

    private static final String[] NAMES;

    static {
        try {
            final BufferedReader in = new BufferedReader(new InputStreamReader(
                    UserAgents.class.getResourceAsStream("useragents.txt"),
                    "utf-8"));
            while (true) {
                final String line = in.readLine();
                if (line == null)
                    break;
                final String[] fields = line.split("=", 2);
                if (fields.length != 2)
                    continue;
                // FIXME: these are names. convert them to lowercase anyway?
                final String name = fields[0].trim().toLowerCase();
                final String header = fields[1].trim();
                USER_AGENTS.put(name, header);
                USER_AGENT_NAMES.add(name);
            }
            in.close();
        } catch (final UnsupportedEncodingException e) {
            // this really should never happen with utf8...
            LOGGER.error("utf8 is invalid", e);
        } catch (final IOException e) {
            LOGGER.error("cannot read useragents.txt", e);
        }

        NAMES = USER_AGENT_NAMES.toArray(new String[0]);
    }

    /**
     * Get an array of the user-visible names of the user agents.
     * 
     * @return all known user agents
     */
    public static String[] getNames() {
        return NAMES;
    }

    /**
     * Get the actual User-Agent: header value for the given name.
     * 
     * @param name
     *            the user agent's name
     * @return the user agent's User-Agent: header value
     */
    public static String getUserAgent(final String name) {
        if (USER_AGENTS.containsKey(name))
            return name;
        return USER_AGENTS.get(name);
    }

    /**
     * Get a suitable default user agent.
     * 
     * @return the default user agent's User-Agent: header value
     */
    public static String getDefault() {
        if (NAMES.length == 0)
            return null;
        return getUserAgent(NAMES[0]);
    }
}
