/*
 * Copyright (C) 2016 Charles Brophy
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.granite.io;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;

import com.google.common.base.CharMatcher;
import com.google.common.collect.ImmutableList;
import com.google.common.io.Resources;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.net.URL;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.zip.GZIPInputStream;
import org.granite.base.ExceptionTools;
import org.granite.base.StringTools;
import org.granite.log.LogTools;

public final class ResourceTools implements Serializable {

  private ResourceTools() {
  }

  public static InputStream readResource(final String resourceName) {
    checkNotNull(resourceName, "resourceName");

    try {

      final URL resourceUrl = Resources.getResource(resourceName);

      checkNotNull(resourceUrl, "Unknown resource: %s", resourceName);

      return Resources.asByteSource(resourceUrl).openStream();
    } catch (IOException e) {
      throw ExceptionTools.checkedToRuntime(e);
    } catch (IllegalArgumentException ignored) {
      LogTools.warn("Resource {0} does not exist", resourceName);
    }

    return null;
  }

  public static <T> List<T> readResourceTextFile(
      final String resourceName,
      final int skipRows,
      final Function<String, Boolean> rowFilter,
      final Function<String, T> rowDeserializer) {

    checkNotNull(resourceName, "resourceName");
    checkArgument(resourceName.trim().length() > 0, "Resource name is empty");
    checkNotNull(rowDeserializer, "rowDeserializer");
    checkNotNull(rowFilter, "rowFilter");

    final ImmutableList.Builder<T> resultBuilder = ImmutableList.builder();

    final InputStream resourceStream = ResourceTools.readResource(resourceName);

    checkNotNull(resourceStream, "Could not load resource: %s", resourceName);

    try (BufferedReader reader = new BufferedReader(new InputStreamReader(
        resourceName.endsWith(".gz") ? new GZIPInputStream(resourceStream) : resourceStream
    ))) {

      String line = null;

      int rowCount = 0;

      while ((line = reader.readLine()) != null) {
        if (rowCount >= skipRows) {

          if (rowFilter.apply(line)) {
            resultBuilder.add(rowDeserializer.apply(line));
          }
        }

        rowCount++;
      }

    } catch (IOException e) {
      throw ExceptionTools.checkedToRuntime(e);
    }

    return resultBuilder.build();
  }

  public static List<String> readResourceTextFile(final String resourceName) {

    return readResourceTextFile(
        resourceName,
        0,
        row -> !StringTools.isNullOrEmpty(row),
        String::trim
    );
  }

  public static Map<String, String> readResourceTextFileAsMap(final String resourceName) {

    checkNotNull(resourceName, "resourceName");

    return StringTools
        .convertStringsToMap(readResourceTextFile(resourceName), CharMatcher.is('='), false);

  }
}

@@ -2521,36 +2521,26 @@
 Name);%0A%0A    
-checkNotNull
+if
 (resourceStr
@@ -2546,57 +2546,23 @@
 ream
-, %22Could not load resource: %25s%22, resourceName);%0A%0A
+ != null) %7B%0A%0A  
     
@@ -2632,16 +2632,18 @@
 Reader(%0A
+  
         
@@ -2734,15 +2734,19 @@
     
+  
 ))) %7B%0A%0A
+  
     
@@ -2768,16 +2768,18 @@
  null;%0A%0A
+  
       in
@@ -2801,16 +2801,18 @@
 %0A%0A      
+  
 while ((
@@ -2852,24 +2852,26 @@
 ) %7B%0A        
+  
 if (rowCount
@@ -2883,24 +2883,26 @@
 kipRows) %7B%0A%0A
+  
           if
@@ -2940,16 +2940,18 @@
         
+  
 resultBu
@@ -3000,18 +3000,22 @@
         
-%7D%0A
+  %7D%0A  
         
@@ -3025,16 +3025,18 @@
         
+  
 rowCount
@@ -3041,27 +3041,31 @@
 nt++;%0A      
+  
 %7D%0A%0A
+  
     %7D catch 
@@ -3080,32 +3080,34 @@
 tion e) %7B%0A      
+  
 throw ExceptionT
@@ -3128,24 +3128,121 @@
 Runtime(e);%0A
+      %7D%0A    %7D else %7B%0A      LogTools.warn(%22Could not find embedded resource: %7B0%7D%22, resourceName);%0A
     %7D%0A%0A    r

Fix NPE when resource not found