/* UtilLib - Copyright (c) 2014 Vincent Calame - Exemole
 * Logiciel libre donné sous triple licence :
 * 1) selon les termes de la CeCILL V2
 * 2) selon les termes de l’EUPL V.1.1
 * 3) selon les termes de la GNU GPLv3
 * Voir le fichier licences.txt
 */


package net.mapeadores.util.mimetype;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.util.HashMap;
import java.util.Map;
import net.mapeadores.util.text.StringUtils;


/**
 *
 * @author Vincent Calame
 */
public class MimeTypeResolverBuilder {

    private final Map<String, String> mimeTypeByExtensionMap = new HashMap<String, String>();
    private final Map<String, String> extensionByMimeTypeMap = new HashMap<String, String>();

    public MimeTypeResolver toMimeTypeResolver() {
        return new InternalMimeTypeResolver(mimeTypeByExtensionMap, extensionByMimeTypeMap);
    }

    public void parseLine(String lineString) {
        lineString = lineString.trim();
        int length = lineString.length();
        if (length == 0) {
            return;
        }
        if (lineString.startsWith("#")) {
            return;
        }
        StringBuilder mimeTypeBuilder = new StringBuilder();
        int whiteCarac = -1;
        for (int i = 0; i < length; i++) {
            char carac = lineString.charAt(i);
            if (Character.isWhitespace(carac)) {
                whiteCarac = i;
                break;
            }
            mimeTypeBuilder.append(carac);
        }
        if (whiteCarac == -1) {
            return;
        }
        String extensionString = lineString.substring(whiteCarac).trim();
        String[] tokens = StringUtils.getTokens(extensionString, ' ', StringUtils.EMPTY_EXCLUDE);
        String mimeType = mimeTypeBuilder.toString();
        String firstExtension = tokens[0];
        if (!extensionByMimeTypeMap.containsKey(mimeType)) {
            extensionByMimeTypeMap.put(mimeType, firstExtension);
        }
        int tokenCount = tokens.length;
        for (int i = 0; i < tokenCount; i++) {
            String token = tokens[i];
            if (!mimeTypeByExtensionMap.containsKey(token)) {
                mimeTypeByExtensionMap.put(token, mimeType);
            }
        }
    }

    public void parse(Reader reader) throws IOException {
        BufferedReader bufReader = new BufferedReader(reader);
        String lineString;
        while ((lineString = bufReader.readLine()) != null) {
            parseLine(lineString);
        }
    }


    private static class InternalMimeTypeResolver implements MimeTypeResolver {

        private final Map<String, String> mimeTypeByExtensionMap;
        private final Map<String, String> extensionByMimeTypeMap;

        private InternalMimeTypeResolver(Map<String, String> mimeTypeByExtensionMap, Map<String, String> extensionByMimeTypeMap) {
            this.mimeTypeByExtensionMap = mimeTypeByExtensionMap;
            this.extensionByMimeTypeMap = extensionByMimeTypeMap;
        }

        @Override
        public String getMimeType(String extension) {
            String mimeType = mimeTypeByExtensionMap.get(extension);
            if (mimeType == null) {
                return MimeTypeConstants.OCTETSTREAM;
            } else {
                return mimeType;
            }
        }

        @Override
        public String getPreferredExtension(String mimeType) {
            return extensionByMimeTypeMap.get(mimeType);
        }

    }

}
