/**
 * Copyright (C) 2013 Microsoft Corporation
 *
 * 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 com.microsoft.reef.utils;

import com.microsoft.tang.formats.ConfigurationModule;
import com.microsoft.tang.formats.OptionalParameter;
import com.microsoft.tang.formats.Param;

import java.io.File;
import java.util.HashSet;
import java.util.Set;

public final class EnvironmentUtils {

  public static String getReefHome() {
    final String reefHome = System.getProperty("REEF_HOME", System.getenv("REEF_HOME"));
    assert (null != reefHome) : "REEF_HOME is not set";
    return reefHome;
  }

  public static String getReefVersion() {
    final String envVersion = System.getenv("REEF_VERSION");
    return System.getProperty("REEF_VERSION", envVersion == null ? "0.1-SNAPSHOT" : envVersion);
  }

  public static String getClassLocationFile(final Class<?> clazz) {
    return clazz.getProtectionDomain().getCodeSource().getLocation().getFile();
  }

  /**
   * Get a set of all classpath entries EXCEPT of those under
   * $JAVA_HOME, $YARN_HOME, and $HADOOP_HOME.
   *
   * @return A set of classpath entries as strings.
   */
  public static Set<String> getAllClasspathJars() {
    return getAllClasspathJars("JAVA_HOME", "YARN_HOME", "HADOOP_HOME");
  }

  /**
   * Get a set of all classpath entries EXCEPT of those under excludeEnv directories.
   * Every excludeEnv entry is an environment variable name.
   *
   * @return A set of classpath entries as strings.
   */
  public static Set<String> getAllClasspathJars(final String... excludeEnv) {

    final Set<String> jars = new HashSet<>();
    final Set<String> excludePaths = new HashSet<>();

    for (final String env : excludeEnv) {
      final File file = new File(env);
      if (file.exists()) {
        excludePaths.add(file.getAbsolutePath());
      }
    }

    for (final String path : System.getProperty("java.class.path").split(File.pathSeparator)) {
      final File file = new File(path);
      if (file.exists()) {
        final String absolutePath = file.getAbsolutePath();
        boolean toBeAdded = true;
        for (final String prefix : excludePaths) {
          if (absolutePath.startsWith(prefix)) {
            toBeAdded = false;
          }
        }
        if (toBeAdded) {
          jars.add(absolutePath);
        }
      }
    }

    return jars;
  }

  public static <P extends Param> ConfigurationModule addAll(
      ConfigurationModule config, final P param, final Iterable<String> values) {
    for (final String val : values) {
      config = config.set(param, val);
    }
    return config;
  }

  public static ConfigurationModule addClasspath(
      ConfigurationModule config, final OptionalParameter<String> param) {
    return addAll(config, param, getAllClasspathJars());
  }
}

@@ -809,24 +809,52 @@
 va.io.File;%0A
+import java.io.IOException;%0A
 import java.
@@ -893,46 +893,200 @@
 et;%0A
-%0Apublic final class EnvironmentUtils %7B
+import java.util.logging.Level;%0Aimport java.util.logging.Logger;%0A%0Apublic final class EnvironmentUtils %7B%0A%0A  private static final Logger LOG = Logger.getLogger(EnvironmentUtils.class.getName());
 %0A%0A  
@@ -2393,24 +2393,38 @@
 cludeEnv) %7B%0A
+      try %7B%0A  
       final 
@@ -2448,32 +2448,34 @@
 ile(env);%0A      
+  
 if (file.exists(
@@ -2487,16 +2487,18 @@
         
+ 
+ 
 excludeP
@@ -2514,30 +2514,173 @@
 file.get
-AbsolutePath()
+CanonicalPath());%0A        %7D%0A      %7D catch (final IOException ex) %7B%0A        LOG.log(Level.FINE, %22Skip environment variable %7B0%7D: %7B1%7D%22, new Object%5B%5D %7B env, ex %7D
 );%0A     
@@ -2781,24 +2781,38 @@
 parator)) %7B%0A
+      try %7B%0A  
       final 
@@ -2835,24 +2835,26 @@
 File(path);%0A
+  
       if (fi
@@ -2872,24 +2872,26 @@
 ) %7B%0A        
+  
 final String
@@ -2918,24 +2918,25 @@
 .get
-Absolute
+Canonical
 Path();%0A
     
@@ -2927,24 +2927,26 @@
 icalPath();%0A
+  
         bool
@@ -2967,16 +2967,18 @@
 = true;%0A
+  
         
@@ -3026,24 +3026,26 @@
 %7B%0A          
+  
 if (absolute
@@ -3083,16 +3083,18 @@
         
+  
 toBeAdde
@@ -3104,16 +3104,18 @@
  false;%0A
+  
         
@@ -3118,34 +3118,38 @@
       %7D%0A        
-%7D%0A
+  %7D%0A  
         if (toBe
@@ -3167,16 +3167,18 @@
         
+ 
+ 
 jars.add
@@ -3193,33 +3193,163 @@
 ePath);%0A        
-%7D
+  %7D%0A        %7D%0A      %7D catch (final IOException ex) %7B%0A        LOG.log(Level.FINE, %22Skip path: %7B0%7D: %7B1%7D%22, new Object%5B%5D %7B path, ex %7D);
 %0A      %7D%0A    %7D%0A%0A

use File.getCanonicalPath() instead of getAbsolutePath() in EnvironmentUtils - should fix #596