package io.github.spharris.pvwatts.service.weather;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.Comparator;

import com.google.common.collect.ImmutableList;

/**
 * A weather source that reads weather files from the specified directory and finds the one closest
 * to the specified latitude and longitude. 
 */
public class LocalDirectoryWeatherSource implements WeatherSource {
  
  private final Path path;
  private final WeatherSummarizer summarizer;
  
  public LocalDirectoryWeatherSource(String directory, WeatherSummarizer summarizer) {
    this.path = Paths.get(directory);
    this.summarizer = summarizer;
  }
  
  @Override
  public String getWeatherFile(Float lat, Float lon, Integer radius) {
    if (lat == null || lon == null || radius == null) {
      return null;
    }

    WeatherDataRecord closestStation = Collections.min(loadSummaryData(), byDistanceFrom(lat, lon));
    double distance = Haversine.haversine(
      closestStation.getLat(), closestStation.getLon(), lat, lon);
    
    if (radius != 0 && distance > (double) radius) {
      return null;
    }

    return path.resolve(closestStation.getFilename()).toString();
  }
  
  private ImmutableList<WeatherDataRecord> loadSummaryData() {
    
    ImmutableList.Builder<WeatherDataRecord> builder = ImmutableList.builder();
    File[] files = path.toFile().listFiles();
    for (File file : files) {
      // TODO(spharris): Recurse into subdirectories?
      if (file.isFile()) {
        try(Reader reader = new FileReader(file)) {
          builder.add(summarizer.summarizeFile(reader));
        } catch (IOException e) {
          // TODO(spharris): Anything to do here?
        }
      }
    }

    return builder.build();
  }
  
  private Comparator<WeatherDataRecord> byDistanceFrom(final float lat, final float lon) {
    return (left, right) -> {
        double leftDist = Haversine.haversine(left.getLat(), left.getLon(), lat, lon);
        double rightDist = Haversine.haversine(right.getLat(), right.getLon(), lat, lon);
        
        return Double.compare(leftDist, rightDist);
    };
  }
}

@@ -200,16 +200,41 @@
 .Paths;%0A
+import java.util.Arrays;%0A
 import j
@@ -283,16 +283,78 @@
 parator;
+%0Aimport java.util.Objects;%0Aimport java.util.stream.Collectors;
 %0A%0Aimport
@@ -1471,241 +1471,205 @@
     
-ImmutableList.Builder%3CWeatherDataRecord%3E builder = ImmutableList.builder();%0A    File%5B%5D files = path.toFile().listFiles();%0A    for (File file : files) %7B%0A      // TODO(spharris): Recurse into subdirectories?%0A      if (file.isFile()) %7B%0A
+File%5B%5D files = path.toFile().listFiles();%0A    return ImmutableList.%3CWeatherDataRecord%3EcopyOf(%0A      Arrays.stream(files).parallel()%0A          .filter(File::isFile)%0A          .map((file) -%3E %7B%0A      
     
@@ -1730,20 +1730,21 @@
     
-builder.add(
+      return 
 summ
@@ -1771,19 +1771,24 @@
 (reader)
-)
 ;%0A
+      
         
@@ -1827,56 +1827,36 @@
     
-// TODO(spharris): Anything to do here?%0A
+      return null;%0A 
         
 %7D%0A  
@@ -1855,16 +1855,21 @@
     
+     
 %7D%0A      
 %7D%0A  
@@ -1868,42 +1868,90 @@
     
+ 
-%7D
+   %7D)
 %0A    
-%7D%0A%0A
+  
     
-return builder.build(
+.filter(Objects::nonNull)%0A          .collect(Collectors.toList())
 );%0A 

Use a stream instead of iteration for going through the files