package de.hft.stuttgart.citygml.green.kataster;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

import org.geotools.data.DataStore;
import org.geotools.data.DataStoreFinder;
import org.geotools.data.FeatureSource;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureIterator;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;

public class StandardTreeFinder {
	
	public static void main(String[] args) throws IOException {
		
		File f = new File("data/Baum.shp");
		
		Map<String, AtomicInteger> treeTypes = new HashMap<>();
		List<Integer> ages = new ArrayList<>();
		List<Integer> treeHeights = new ArrayList<>();
		List<Float> crownWidths = new ArrayList<>();
		List<Integer> trunkCircs = new ArrayList<>();
		
        Map<String, Object> map = new HashMap<>();
        map.put("url", f.toURI().toURL());
        map.put("charset", StandardCharsets.UTF_8);

        DataStore dataStore = DataStoreFinder.getDataStore(map);
        String typeName = dataStore.getTypeNames()[0];

        FeatureSource<SimpleFeatureType, SimpleFeature> source =
                dataStore.getFeatureSource(typeName);

        int featureCount = 0;
        FeatureCollection<SimpleFeatureType, SimpleFeature> collection = source.getFeatures();
        try (FeatureIterator<SimpleFeature> features = collection.features()) {
            while (features.hasNext()) {
            	featureCount++;
                SimpleFeature feature = features.next();
                String type = feature.getAttribute("Baumart").toString();
                treeTypes.compute(type, (k, v) -> {
                	if (v == null) {
                		v = new AtomicInteger(0);
                	}
                	v.incrementAndGet();
                	return v;
                });
                Object ageObject = feature.getAttribute("Alter am S");
                if (ageObject != null) {
                	ages.add(Integer.parseInt(ageObject.toString()));
                }
                Object treeHeight = feature.getAttribute("Baumhöhe");
                if (treeHeight != null) {
                	treeHeights.add(Integer.parseInt(treeHeight.toString()));
                }
                Object crownWidth = feature.getAttribute("Kronenbrei");
                if (crownWidth != null) {
                	crownWidths.add(Float.parseFloat(crownWidth.toString()));
                }
                Object trunkCirc = feature.getAttribute("Stammumfan");
                if (trunkCirc != null) {
                	trunkCircs.add(Integer.parseInt(trunkCirc.toString()));
                }
            }
        }
        
        System.out.println("Number of trees: " + featureCount);
        
        for (Entry<String, AtomicInteger> e : treeTypes.entrySet()) {
        	System.out.println(e.getKey() + ": " + e.getValue());
        }
        
        System.out.println();
        IntSummaryStatistics treeHeightsStatistics = treeHeights.stream().collect(Collectors.summarizingInt(Integer::intValue));
        System.out.println("TreeHeightAverage: " + treeHeightsStatistics.getAverage());
        
        IntSummaryStatistics agesStatistics = ages.stream().collect(Collectors.summarizingInt(Integer::intValue));
		System.out.println("AverageAge: " + agesStatistics);
		
		Double averageCrown = crownWidths.stream().collect(Collectors.averagingDouble(Float::doubleValue));
		System.out.println("AverageCrownWidth: " + averageCrown);
		
		Double averageTrunkCirc = trunkCircs.stream().collect(Collectors.averagingInt(Integer::intValue));
		System.out.println("AverageTrunkCirc: " + averageTrunkCirc);
	}

}
