package liquibase.util;

import liquibase.exception.UnexpectedLiquibaseException;
import liquibase.integration.commandline.CommandLineUtils;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Properties;
import java.util.jar.Attributes;
import java.util.jar.Manifest;

public class LiquibaseUtil {

    public static String getBuildVersion() {
        return getBuildInfo("build.version","Bundle-Version");
    }

    public static String getBuildTime() {
        return getBuildInfo("build.timestamp", "Build-Time");
    }

    // will extract the information from either buildinfo.properties, which should be a properties file in
    // the jar file, or from the jar file's MANIFEST.MF, which should also have similar information.
    private static String getBuildInfo(String propertyId, String manifestId) {
        String buildVersion = "UNKNOWN";
        Properties buildInfo = new Properties();
        ClassLoader classLoader = LiquibaseUtil.class.getClassLoader();

        URL buildInfoFile = classLoader.getResource("buildinfo.properties");
        InputStream in = null;
        try {
            if (buildInfoFile != null) {
                URLConnection connection = buildInfoFile.openConnection();
                connection.setUseCaches(false);
                in = connection.getInputStream();
                buildInfo.load(in);
                String o = (String) buildInfo.get(propertyId);

                if (o != null) {
                    buildVersion = o;
                }
            } else {
                Class clazz = LiquibaseUtil.class;
                String className = clazz.getSimpleName() + ".class";
                String classPath = clazz.getResource(className).toString();
                if (classPath.startsWith("jar")) {
                    String manifestPath = classPath.substring(0, classPath.lastIndexOf("!") + 1) +
                            "/META-INF/MANIFEST.MF";
                    Manifest manifest = null;
                    try {
                        manifest = new Manifest(new URL(manifestPath).openStream());
                    } catch (IOException e) {
                        throw new UnexpectedLiquibaseException("Cannot open a URL to the manifest of our own JAR file.");
                    }
                    Attributes attr = manifest.getMainAttributes();
                    buildVersion = attr.getValue(manifestId);
                }
            }

        } catch (IOException e) {
            // This is not a fatal exception.
            // Build info will be returned as 'UNKNOWN'        }
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    // TODO Log this error and remove the RuntimeException.
                    throw new RuntimeException("Failed to close InputStream in LiquibaseUtil.", e);
                }
            }
        }
        return buildVersion;
    }
}

@@ -900,23 +900,25 @@
 ng build
-Version
+InfoValue
  = %22UNKN
@@ -927,684 +927,9 @@
 N%22;%0A
-        Properties buildInfo = new Properties();%0A        ClassLoader classLoader = LiquibaseUtil.class.getClassLoader();%0A%0A        URL buildInfoFile = classLoader.getResource(%22buildinfo.properties%22);%0A        InputStream in = null;%0A        try %7B%0A            if (buildInfoFile != null) %7B%0A                URLConnection connection = buildInfoFile.openConnection();%0A                connection.setUseCaches(false);%0A                in = connection.getInputStream();%0A                buildInfo.load(in);%0A                String o = (String) buildInfo.get(propertyId);%0A%0A                if (o != null) %7B%0A                    buildVersion = o;%0A                %7D%0A            %7D else %7B%0A        
+%0A
     
@@ -967,24 +967,16 @@
 .class;%0A
-        
         
@@ -1032,32 +1032,24 @@
 s%22;%0A        
-   
-     
 String class
@@ -1092,32 +1092,24 @@
 toString();%0A
-        
         if (
@@ -1151,24 +1151,16 @@
         
-        
 String m
@@ -1250,24 +1250,16 @@
         
-    
-    
 %22/META-I
@@ -1275,24 +1275,16 @@
 ST.MF%22;%0A
-        
         
@@ -1321,32 +1321,24 @@
             
- 
-       
 try %7B%0A      
@@ -1347,24 +1347,16 @@
         
-     
-   
 manifest
@@ -1416,32 +1416,24 @@
             
-        
 %7D catch (IOE
@@ -1458,32 +1458,24 @@
             
-  
-      
 throw new Un
@@ -1572,34 +1572,18 @@
         
-      
-  %7D%0A        
+%7D%0A
         
@@ -1650,58 +1650,798 @@
     
-        buildVersion = attr.getValue(manifestId);%0A
+buildInfoValue = attr.getValue(manifestId);%0A        %7D%0A%0A        if (buildInfoValue.equals(%22UNKNOWN%22)) %7B%0A            Properties buildInfo = new Properties();%0A            ClassLoader classLoader = LiquibaseUtil.class.getClassLoader();%0A%0A            URL buildInfoFile = classLoader.getResource(%22buildinfo.properties%22);%0A            InputStream in = null;%0A            try %7B%0A                if (buildInfoFile != null) %7B%0A                    URLConnection connection = buildInfoFile.openConnection();%0A                    connection.setUseCaches(false);%0A                    in = connection.getInputStream();%0A                    buildInfo.load(in);%0A                    String o = (String) buildInfo.get(propertyId);%0A%0A                    if (o != null) %7B%0A                        buildInfoValue = o;%0A    
     
@@ -2446,32 +2446,36 @@
               %7D%0A
+    
             %7D%0A%0A 
@@ -2473,32 +2473,36 @@
      %7D%0A%0A        
+ 
+   
 %7D catch (IOExcep
@@ -2519,24 +2519,28 @@
             
+   
+ 
 // This is n
@@ -2553,32 +2553,36 @@
 atal exception.%0A
+    
             // B
@@ -2638,16 +2638,20 @@
         
+ 
+   
 %7D finall
@@ -2650,24 +2650,28 @@
 %7D finally %7B%0A
+    
             
@@ -2696,32 +2696,36 @@
                 
+    
 try %7B%0A          
@@ -2734,16 +2734,20 @@
         
+  
+  
 in.close
@@ -2746,24 +2746,28 @@
 in.close();%0A
+    
             
@@ -2788,32 +2788,36 @@
 OException e) %7B%0A
+    
                 
@@ -2888,32 +2888,36 @@
                 
+  
+  
 throw new Runtim
@@ -2976,24 +2976,46 @@
 Util.%22, e);%0A
+                    %7D%0A
             
@@ -3064,23 +3064,25 @@
 rn build
-Version
+InfoValue
 ;%0A    %7D%0A

use values in MANIFEST.MF before build.properties