/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.csu.sdmx.validation;

import cz.csu.sdmx.Utils;
import cz.csu.sdmx.validation.model.Input;
import cz.csu.sdmx.validation.model.dsds.Dsd;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.w3c.dom.ls.LSInput;
import org.w3c.dom.ls.LSResourceResolver;

/**
 *
 * @author themi
 */
public class SDMXResourceResolver implements LSResourceResolver {
    private static final String RESOURCE_VALIDATION_DIR = "validation/";
    
    private static final Map<String, String> RESOURCES = createResourceMap();

    private static Map<String, String> createResourceMap() {
        Map<String, String> map = new HashMap<>();
        map.put("http://www.w3.org/XML/1998/namespace", "xml.xsd");
        map.put("http://www.w3.org/2001/XMLSchema", "xmlSchema.xsd");
        map.put("http://www.SDMX.org/resources/SDMXML/schemas/v2_0/utility", "SDMXUtilityData.xsd");
        map.put("http://www.SDMX.org/resources/SDMXML/schemas/v2_0/structure", "SDMXStructure.xsd");
        map.put("http://www.SDMX.org/resources/SDMXML/schemas/v2_0/registry", "SDMXRegistry.xsd");
        map.put("http://www.SDMX.org/resources/SDMXML/schemas/v2_0/query", "SDMXQuery.xsd");
        map.put("http://www.SDMX.org/resources/SDMXML/schemas/v2_0/metadatareport", "SDMXMetadataReport.xsd");
        map.put("http://www.SDMX.org/resources/SDMXML/schemas/v2_0/message", "SDMXMessage.xsd");
        map.put("http://www.SDMX.org/resources/SDMXML/schemas/v2_0/genericmetadata", "SDMXGenericMetadata.xsd");
        map.put("http://www.SDMX.org/resources/SDMXML/schemas/v2_0/generic", "SDMXGenericData.xsd");
        map.put("http://www.SDMX.org/resources/SDMXML/schemas/v2_0/cross", "SDMXCrossSectionalData.xsd");
        map.put("http://www.SDMX.org/resources/SDMXML/schemas/v2_0/compact", "SDMXCompactData.xsd");
        map.put("http://www.SDMX.org/resources/SDMXML/schemas/v2_0/common", "SDMXCommon.xsd");
        
        return map;
    }
    
    private List<Dsd> dsds;
    
    public SDMXResourceResolver(List<Dsd> dsds) {
        this.dsds = dsds;
    }

    @Override
    public LSInput resolveResource(String type, String namespaceURI, String publicId, String systemId, String baseURI){
        InputStream is = null;
        
        //if is urn of DSD which everytime starts with 'urn:'
        if(namespaceURI.contains("urn:")){
            for(Dsd dsd : dsds){
                if(dsd.getURN().equals(namespaceURI)){
                    is = Utils.docToIS(dsd.getDocument()); 
                }
            }
        }
        
        //if is one of stored resources
        if(RESOURCES.containsKey(namespaceURI)){
            String filename = RESOURCES.get(namespaceURI);
            is =  getClass().getClassLoader().getResourceAsStream(RESOURCE_VALIDATION_DIR + filename);
        }
        
        //if resource is not recognised
        if (is == null) 
            throw new NoResourceFoundException(namespaceURI);
                                            
        return new Input(publicId, systemId, is);
    }
    
    
    class NoResourceFoundException extends NullPointerException{
    
        private String URI;

        public NoResourceFoundException(String URI) {
            this.URI = URI;
        }

        @Override
        public String getMessage() {
            return "Did not find resource for namespace: " + URI;
        }
    }
}
