package com.agile.train.util;

import com.agile.train.dto.SourceFile;
import com.google.common.collect.Lists;
import org.apache.commons.io.IOUtils;

import java.io.*;
import java.util.Collections;
import java.util.List;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class PinganCodeUtil {

    public static String readSourceCodeByFileNameInJar(String jarFileName, String fileName) throws IOException {
        ZipInputStream jarFileInputStream = null;
        try {
            jarFileInputStream = new ZipInputStream(new FileInputStream(jarFileName));
            StringBuilder result = readSourceFileInJar(fileName, jarFileInputStream);
            jarFileInputStream.closeEntry();
            IOUtils.closeQuietly(jarFileInputStream);
            return result.toString();
        } finally {
            IOUtils.closeQuietly(jarFileInputStream);
        }
    }

    private static StringBuilder readSourceFileInJar(String fileName, ZipInputStream jarFileInputStream) throws IOException {
        StringBuilder result = new StringBuilder();
        ZipEntry entry;
        while ((entry = jarFileInputStream.getNextEntry()) != null) {
            if (!entry.getName().equals(fileName)) continue;

            BufferedReader sourceCode = new BufferedReader(new InputStreamReader(jarFileInputStream));

            String line;
            while ((line = sourceCode.readLine()) != null)
                result.append(line).append("\n");

            break;
        }
        return result;
    }

    public static List<SourceFile> searchFileInRepositoryByKeyword(String repositoryPath, String searchKeyword) throws IOException {
        File repository = new File(repositoryPath);
        File[] files = repository.listFiles();

        if (files == null || files.length == 0) return Collections.emptyList();

        List<SourceFile> result = Lists.newArrayList();
        for (File file : files) {
            if (file.isDirectory()) continue;

            result.addAll(searchFileInJarByKeyword(file, searchKeyword));
        }

        return result;
    }

    private static List<SourceFile> searchFileInJarByKeyword(File jarFile, String searchKeyword) throws IOException {
        ZipInputStream jarFileInputStream = null;
        try {
            jarFileInputStream = new ZipInputStream(new FileInputStream(jarFile));
            List<SourceFile> result = Lists.newArrayList();
            ZipEntry entry;
            while ((entry = jarFileInputStream.getNextEntry()) != null) {
                String path = entry.getName();
                if (path.endsWith(".java") && path.contains(searchKeyword)) {
                    result.add(new SourceFile(jarFile.getName(), retrieveVersionInJar(jarFile), path));
                }
            }
            IOUtils.closeQuietly(jarFileInputStream);
            return result;
        } finally {
            IOUtils.closeQuietly(jarFileInputStream);
        }
    }


    public static String retrieveVersionInJar(File jarFile) throws IOException {
        JarFile jar = null;
        try {
            jar = new JarFile(jarFile);
            Manifest manifest = jar.getManifest();

            String version = "";
            Attributes attributes = manifest.getMainAttributes();
            if (attributes != null) {
                for (Object o : attributes.keySet()) {
                    Attributes.Name key = (Attributes.Name) o;
                    String keyword = key.toString();
                    if (keyword.equals("Implementation-Version") || keyword.equals("Bundle-Version")) {
                        version = (String) attributes.get(key);
                        break;
                    }
                }
            }
            jar.close();

            return version;
        } finally {
            if (jar != null) jar.close();
        }
    }
}

@@ -681,39 +681,32 @@
           String
-Builder
  result = readSo
@@ -874,27 +874,16 @@
 n result
-.toString()
 ;%0A      
@@ -992,23 +992,16 @@
 c String
-Builder
  readSou
@@ -1090,60 +1090,8 @@
 n %7B%0A
-        StringBuilder result = new StringBuilder();%0A
     
@@ -1196,17 +1196,16 @@
     if (
-!
 entry.ge
@@ -1230,31 +1230,276 @@
 eName)) 
-continue;%0A%0A    
+%7B%0A                return readSourceCode(jarFileInputStream);%0A            %7D%0A        %7D%0A        return %22%22;%0A    %7D%0A%0A    private static String readSourceCode(ZipInputStream jarFileInputStream) throws IOException %7B%0A        StringBuilder result = new StringBuilder();%0A
         
@@ -1594,28 +1594,24 @@
 );%0A%0A        
-  
-  
 String line;
@@ -1611,20 +1611,16 @@
 g line;%0A
-    
         
@@ -1665,21 +1665,19 @@
 != null)
-%0A    
+ %7B%0A
         
@@ -1714,25 +1714,24 @@
 (%22%5Cn%22);%0A
-%0A
         
     brea
@@ -1726,28 +1726,10 @@
     
-    break;%0A        
 %7D
+%0A
 %0A   
@@ -1738,32 +1738,43 @@
    return result
+.toString()
 ;%0A    %7D%0A%0A    pub
@@ -2020,25 +2020,8 @@
 iles
- == null %7C%7C files
 .len
@@ -3175,17 +3175,16 @@
 %0A    %7D%0A%0A
-%0A
     publ
@@ -3516,25 +3516,25 @@
 ributes 
-!
+=
 = null) 
 %7B%0A      
@@ -3517,38 +3517,44 @@
 ibutes == null) 
-%7B%0A    
+return %22%22;%0A%0A
             for 
@@ -3561,17 +3561,25 @@
 (Object 
-o
+attribute
  : attri
@@ -3592,28 +3592,24 @@
 keySet()) %7B%0A
-    
             
@@ -3656,15 +3656,19 @@
 me) 
-o;%0A    
+attribute;%0A
     
@@ -3708,28 +3708,24 @@
 toString();%0A
-    
             
@@ -3832,20 +3832,16 @@
         
-    
 version 
@@ -3896,41 +3896,15 @@
     
-    
 break;%0A
-                    %7D%0A
     

refactor code