/*
 * 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.model.data;

import cz.csu.sdmx.validation.model.DataSet;
import cz.csu.sdmx.validation.model.Obs;
import cz.csu.sdmx.validation.model.Series;
import cz.csu.sdmx.validation.model.dsds.Dsd;
import cz.csu.sdmx.validation.xml.XmlHandler;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.NodeList;

/**
 *
 * @author themi
 */
public class CompactData extends SDMXData{
    
    public CompactData(Document doc) {
        super(doc);
    }
    
    private Map<String, String> parseAttrs(Element el){
        Map<String, String> attrs = new HashMap<>();
        NamedNodeMap attrsMap = el.getAttributes();
        for(int i = 0; i < attrsMap.getLength(); i++){
            Attr attr = (Attr) attrsMap.item(i);
            attrs.put(attr.getName(), attr.getValue());
        }
        
        return attrs;
    }

    private List<Obs> parseObs(Element seriesEl, String obsElementName) {
        List<Obs> obsList = new ArrayList<>();
        NodeList obsNodes = seriesEl.getElementsByTagNameNS("*", obsElementName);
        
        for(int i = 0; i < obsNodes.getLength(); i++){
            Element obsEl = (Element) obsNodes.item(i);
            
            //get line number of observation added during XML parsing
            String lineNumber = (String) obsEl.getUserData(XmlHandler.LINE_NUMBER_KEY_NAME);
            Map<String, String> attrs = parseAttrs(obsEl);
            obsList.add(new Obs(lineNumber, attrs));
        }
        
        return obsList;
    }

    @Override
    public boolean parseDatasets(Dsd dsd) {
        String namespaceUri = dsd.getURN();
        
        NodeList dataSetNodes = doc.getElementsByTagNameNS(namespaceUri, dsd.getDatasetElementName());

        //parse datasets from XML file
        //based on compat data XML structure
        for(int j = 0; j < dataSetNodes.getLength(); j++){
            DataSet dataSet = new DataSet(namespaceUri);
            Element dataSetEl = (Element) dataSetNodes.item(j);
            NodeList seriesNodes = dataSetEl.getElementsByTagNameNS(namespaceUri,dsd.getSeriesElementName());

            for(int i = 0; i < seriesNodes.getLength(); i++){
                Element seriesEl = (Element) seriesNodes.item(i);

                //get line number of series added during XML parsing
                String lineNumber = (String) seriesEl.getUserData(XmlHandler.LINE_NUMBER_KEY_NAME);
                Map<String, String> attrs = parseAttrs(seriesEl);
                
                List<Obs> obsList = parseObs(seriesEl, dsd.getObsElementName());

                dataSet.addSeries(new Series(lineNumber, attrs, obsList));
            }
            dataSetList.add(dataSet);
        }
        
        return dataSetList.size() > 0;
    }
}
