package cpw.mods.fml.common;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Map;
import java.util.logging.Level;

import argo.jdom.JdomParser;
import argo.jdom.JsonNode;
import argo.jdom.JsonRootNode;
import argo.saj.InvalidSyntaxException;

import com.google.common.base.Throwables;
import com.google.common.collect.Maps;

public class MetadataCollection
{
    private static JdomParser parser = new JdomParser();
    private Map<String, ModMetadata> metadatas = Maps.newHashMap();
    private int metadataVersion = 1;

    public static MetadataCollection from(InputStream inputStream, String sourceName)
    {
        if (inputStream == null)
        {
            return new MetadataCollection();
        }

        InputStreamReader reader = new InputStreamReader(inputStream);
        try
        {
            JsonRootNode root = parser.parse(reader);
            if (root.hasElements())
            {
                return parse10ModInfo(root);
            }
            else
            {
                return parseModInfo(root);
            }
        }
        catch (InvalidSyntaxException e)
        {
            FMLLog.log(Level.SEVERE, e, "The mcmod.info file in %s cannot be parsed as valid JSON. It will be ignored", sourceName);
            return new MetadataCollection();
        }
        catch (Exception e)
        {
            throw Throwables.propagate(e);
        }
    }

    private static MetadataCollection parseModInfo(JsonRootNode root)
    {
        MetadataCollection mc = new MetadataCollection();
        mc.metadataVersion = Integer.parseInt(root.getNumberValue("modinfoversion"));
        mc.parseModMetadataList(root.getNode("modlist"));
        return mc;
    }

    private static MetadataCollection parse10ModInfo(JsonRootNode root)
    {
        MetadataCollection mc = new MetadataCollection();
        mc.parseModMetadataList(root);
        return mc;
    }

    private void parseModMetadataList(JsonNode metadataList)
    {
        for (JsonNode node : metadataList.getElements())
        {
            ModMetadata mmd = new ModMetadata(node);
            metadatas.put(mmd.modId, mmd);
        }
    }

    public ModMetadata getMetadataForId(String modId, Map<String, Object> extraData)
    {
        if (!metadatas.containsKey(modId))
        {
            ModMetadata dummy = new ModMetadata();
            dummy.modId = modId;
            dummy.name = (String) extraData.get("name");
            dummy.version = (String) extraData.get("version");
            dummy.autogenerated = true;
            metadatas.put(modId, dummy);
        }
        return metadatas.get(modId);
    }

}
