package com.chenyang.nse.bussiness.config;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.CountDownLatch;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.springframework.stereotype.Component;

@Component
public class PropertiesLoaderUtils {
   public static Properties loadAllProperties(String resourceName) throws IOException {
      Properties properties = loadAllPropertiesInternal(resourceName);
      properties = mergeLocal(resourceName, properties);
      return properties;
   }

   public static Properties loadAllPropertiesInternal(String resourceName) throws IOException {
      String reg = "(\\$\\{)(.*?)(})";
      Pattern compile = Pattern.compile(reg);
      Properties result = new Properties();
      Properties properties = org.springframework.core.io.support.PropertiesLoaderUtils.loadAllProperties(resourceName);

      for(Object object : properties.keySet()) {
         String value = (String)properties.get(object);

         String val;
         for(Matcher matcher = compile.matcher(value); matcher.find(); value = value.replaceAll("\\$\\{" + matcher.group(2) + "}", val)) {
            String key = matcher.group(2);
            val = (String)properties.get(key);
         }

         result.put(object, value);
      }

      return result;
   }

   static Properties loadLocal(String path) throws IOException {
      Properties result = new Properties();
      String reg = "(\\$\\{)(.*?)(})";
      Pattern compile = Pattern.compile(reg);
      Properties properties = new Properties();
      InputStream stream = PropertiesLocalStreamLoader.instance().load(path);

      try {
         properties.load(stream);

         for(Object object : properties.keySet()) {
            String value = (String)properties.get(object);

            String val;
            for(Matcher matcher = compile.matcher(value); matcher.find(); value = value.replaceAll("\\$\\{" + matcher.group(2) + "}", val)) {
               String key = matcher.group(2);
               val = (String)properties.get(key);
            }

            result.put(object, value);
         }
      } finally {
         if (stream != null) {
            try {
               stream.close();
            } catch (IOException e) {
               e.printStackTrace();
            }
         }

      }

      return result;
   }

   static Properties mergeLocal(String resourceName, Properties source) {
      if (resourceName != null && resourceName.length() != 0) {
         String workDirs = System.getProperty("user.dir");
         if (workDirs != null && workDirs.length() != 0) {
            String[] dirs = workDirs.split(":;");
            String local = null;

            for(String dir : dirs) {
               if (dir != null && dir.length() != 0) {
                  String name = dir + "/" + resourceName;
                  File file = new File(name);
                  if (file.exists()) {
                     local = name;
                     break;
                  }
               }
            }

            if (local == null) {
               return source;
            } else {
               try {
                  Properties properties = loadLocal(local);
                  if (properties.size() == 0) {
                     return source;
                  } else if (null != source && source.size() != 0) {
                     for(Map.Entry<Object, Object> pair : properties.entrySet()) {
                        Object key = pair.getKey();
                        Object value = pair.getValue();
                        source.put(key, value);
                     }

                     return source;
                  } else {
                     return properties;
                  }
               } catch (Exception var11) {
                  return source;
               }
            }
         } else {
            return source;
         }
      } else {
         return source;
      }
   }

   public static void main(String[] args) throws IOException, InterruptedException {
      for(int i = 0; i < 10; ++i) {
         Properties properties = loadAllProperties("config.properties");
         System.out.println("0:" + properties.getProperty("api_long_connection_flg"));
      }

      int max = 50;
      CountDownLatch latch = new CountDownLatch(max);
      CountDownLatch a = new CountDownLatch(1);

      for(int i = 0; i < max; ++i) {
         (new Thread(new Test(a, latch, i))).start();
      }

      a.countDown();
      latch.await();
   }

   private static class Test implements Runnable {
      CountDownLatch a;
      CountDownLatch b;
      int k;

      Test(CountDownLatch a, CountDownLatch b, int k) {
         this.a = a;
         this.b = b;
         this.k = k;
      }

      public void run() {
         try {
            this.a.await();
            Properties properties = PropertiesLoaderUtils.loadAllProperties("config.properties");
            System.out.println(this.k + ":" + properties.getProperty("api_long_connection_flg"));
            this.b.countDown();
         } catch (Throwable $ex) {
//            throw $ex;
         }
      }
   }
}
