import sun.net.www.protocol.https.Handler

import java.util.Map.Entry
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors


/**
 * Created by jianpli on 6/29/17.
 */

class Worker implements Runnable
{
    private Entry entry;
    private String resourceDir;
    private String downloadDir;

    Worker(Entry taskEntry,String resDir,String dldDir)
    {
        this.entry = taskEntry;
        this.resourceDir = resDir;
        this.downloadDir = dldDir;
    }

    void run()
    {
        ArrayList<String> urls = entry.getValue()
        for (String aUrl : urls)
        {
            String[] urlInfo = aUrl.split("\\s")
            if (urlInfo.length > 1)
            {
                String licenseFileName = entry.getKey().toString()
                licenseFileName += ","
                licenseFileName += urlInfo[0]
                String licensePath = resourceDir + "/" + downloadDir + "/" + licenseFileName

                File thisLicense = new File(licensePath)
                if (!thisLicense.exists())
                {
                    println "downloading "+entry.getKey().toString() + ":" + urlInfo[1]
                    downloadLicenseFromUrl(entry.getKey().toString(), urlInfo[1], licensePath)
                }
            }
        }
    }

    private void downloadLicenseFromUrl(String GroupIdAndArtifactId, String urlStr, String filePath)
    {
        try
        {
            URL url;
            if (urlStr.startsWith("https"))
            {
                url = new URL(null,urlStr,new Handler())
            }else{
                url = new URL(urlStr)
            }
            HttpURLConnection connection = (HttpURLConnection) url.openConnection()
            // avoid http 403
            connection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)")
            while (connection.getResponseCode() > 299 && connection.getResponseCode() < 400)
            {
                urlStr = connection.getHeaderField("Location")
                if (urlStr.startsWith("https"))
                {
                    url = new URL(null,urlStr,new Handler())
                }else{
                    url = new URL(urlStr)
                }
                connection = (HttpURLConnection) url.openConnection()
                connection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)")
            }
            if (connection.getResponseCode() > 399)
            {
                println "error ---> " + GroupIdAndArtifactId + ", url: " + urlStr + " ---> url 400"
            }

            File file = new File(filePath)
            if (!file.exists())
            {
                file.createNewFile()
            }
            FileOutputStream outputStream = new FileOutputStream(file)

            InputStream inputStream = connection.getInputStream()
            byte[] buffer = new byte[1024]
            int len = 0
            while ((len = inputStream.read(buffer)) != -1)
            {
                outputStream.write(buffer, 0, len)
            }
            outputStream.flush()
            outputStream.close()

            inputStream.close()
        } catch (MalformedURLException)
        {
            println "error ---> " + GroupIdAndArtifactId + ", url: " + urlStr + " ---> url wrong"
        }
    }
}



def resourceDir = "src/main/resources"
def targetDir = project.build.directory
def downloadDir = project.properties['download.licenses.dir']
//def resourceDir = "../resources"
//def targetDir = "../../../target"
//def downloadDir = "download-licenses"

def licenseSummary = new XmlSlurper().parse(targetDir + "/" + downloadDir + "/licenses.xml")
HashMap<String, HashSet<String>> urlMap = new HashMap<>();

for (dependency in licenseSummary.dependencies.dependency)
{
    HashSet<String> urls

    String key = dependency.groupId
    key += ","
    key += dependency.artifactId

    if (urlMap.containsKey(key))
    {
        urls = urlMap.get(key)
    } else
    {
        urls = new HashSet<>()
    }

    for (license in dependency.licenses.license)
    {

        String url = license.name
        url = url.replaceAll("\\s", "")
        url = url + " " + license.url
        urls.add(url)
    }
    urlMap.put(key, urls)
}

File licensesParentPath = new File(resourceDir + "/" + downloadDir)
if (!licensesParentPath.exists())
{
    licensesParentPath.mkdirs()
}

ExecutorService threadPool = Executors.newCachedThreadPool()
for (Map.Entry entry : urlMap.entrySet())
{
    threadPool.execute(new Worker(entry,resourceDir,downloadDir))
}

threadPool.shutdown()
println "info ---> downloading licenses ..."
while(!threadPool.isTerminated())
{
    Thread.sleep(1000)
}
println "info ---> downloaded licenses"

