package com.redhat.chrometwo.api.services;

import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Context;

import com.redhat.chrometwo.api.security.SecurityInterceptor;

import com.redhat.victims.VictimsException;
import com.redhat.victims.VictimsRecord;
import com.redhat.victims.VictimsResultCache;
import com.redhat.victims.VictimsScanner;
import com.redhat.victims.database.VictimsDB;
import com.redhat.victims.database.VictimsDBInterface;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.lang.StringBuilder;

@Path("/check")
@Stateless
@LocalBean
public class Check {

    private int count;

    private String checksum(InputStream body) {
        String hash = null;
        try {
            MessageDigest md = MessageDigest.getInstance("SHA1");
            byte[] buffer = new byte[1024];
            int size;
            count = 0;

            size = body.read(buffer);
            count += size;
            while (size > 0) {
                md.update(buffer);
                size = body.read(buffer);
                count += size;
            }

            byte[] digest = md.digest();
            hash = String.format("%0" + (digest.length << 1) + "X", new BigInteger(1, digest));

        } catch (NoSuchAlgorithmException e) {
        } catch (FileNotFoundException e) {
        } catch (IOException e) {
        }

        return hash;
    }


    @POST
    @Path("/{fileName}")
    public String checkFile(InputStream body,
                            @PathParam("fileName") String fileName,
                            @Context HttpServletRequest request) throws Exception {

        StringBuilder result = new StringBuilder();
        
        result.append("check: ");
        result.append(fileName);
        result.append("\n");

        VictimsDBInterface db;
        VictimsResultCache cache;

        try {
            db = VictimsDB.db();
            cache = new VictimsResultCache();

        } catch (VictimsException e) {
            result.append("VictimsException while opening the database:\n");
            e.printStackTrace();
            return result.append(e.toString()).append("\n").toString();
        }

        String key = checksum(body);
        result.append("key(" + count + ": ");
        result.append(key);
        result.append("\n");
        if (key != null && cache.exists(key)) {
            try {
                HashSet<String> cves = cache.get(key);
                if (cves != null && cves.size() > 0) {
                    result.append(String.format("%s VULNERABLE! ", fileName));
                    for (String cve : cves) {
                        result.append(cve);
                        result.append(" ");
                    }
                    result.append("\n");
                    return result.toString();
                } else {
                    result.append(fileName + " ok\n");
                }
            } catch (VictimsException e) {
                result.append("VictimsException while checking cache:\n");
                e.printStackTrace();
                return result.append(e.toString()).append("\n").toString();
            }
        }
        
        // Scan the item
        ArrayList<VictimsRecord> records = new ArrayList();
        try {
            
            VictimsScanner.scan(fileName, records);
            for (VictimsRecord record : records) {
                
                try {
                    HashSet<String> cves = db.getVulnerabilities(record);
                    if (key != null) {
                        cache.add(key, cves);
                    }
                    if (!cves.isEmpty()) {
                        result.append(String.format("%s VULNERABLE! ", fileName));
                        for (String cve : cves) {
                            result.append(cve);
                            result.append(" ");
                        }
                        result.append("\n");
                        return result.toString();
                    } else {
                        result.append(fileName + " ok\n");
                    }
                    
                } catch (VictimsException e) {
                    result.append("VictimsException while checking database:\n");
                    e.printStackTrace();
                    return result.append(e.toString()).append("\n").toString();
                }
            }
        } catch (IOException e) {
            result.append("VictimsException while scanning file:\n");
            e.printStackTrace();
            return result.append(e.toString()).append("\n").toString();
        }

        result.append("end of results\n");
        return result.toString();
    }
}

@@ -1843,404 +1843,32 @@
     
-@POST%0A    @Path(%22/%7BfileName%7D%22)%0A    public String checkFile(InputStream body,%0A                            @PathParam(%22fileName%22) String fileName,%0A                            @Context HttpServletRequest request) throws Exception %7B%0A%0A        StringBuilder result = new StringBuilder();%0A        %0A        result.append(%22check: %22);%0A        result.append(fileName);%0A        result.append(%22%5Cn%22);%0A%0A        
+private String checkOne(
 Vict
@@ -1884,25 +1884,17 @@
 rface db
-;%0A       
+,
  Victims
@@ -1914,322 +1914,112 @@
 ache
-;%0A%0A        try %7B%0A            db = VictimsDB.db();%0A            cache = new VictimsResultCache();%0A%0A        %7D catch (VictimsException e) %7B%0A            result.append(%22VictimsException while opening the database:%5Cn%22);%0A            e.printStackTrace();%0A            return result.append(e.toString()).append(%22%5Cn%22).toString
+, String fileName, InputStream body) throws Exception %7B%0A        StringBuilder result = new StringBuilder
 ();%0A
@@ -2017,35 +2017,32 @@
 ilder();%0A       
- %7D%0A
 %0A        String 
@@ -2158,32 +2158,33 @@
 t.append(%22%5Cn%22);%0A
+%0A
         if (key 
@@ -4480,32 +4480,919 @@
 g();%0A        %7D%0A%0A
+        return result.toString();%0A    %7D%0A%0A%0A    @POST%0A    @Path(%22/%7BfileName%7D%22)%0A    public String checkFile(InputStream body,%0A                            @PathParam(%22fileName%22) String fileName,%0A                            @Context HttpServletRequest request) throws Exception %7B%0A%0A        StringBuilder result = new StringBuilder();%0A        %0A        result.append(%22check: %22);%0A        result.append(fileName);%0A        result.append(%22%5Cn%22);%0A%0A        VictimsDBInterface db;%0A        VictimsResultCache cache;%0A%0A        try %7B%0A            db = VictimsDB.db();%0A            cache = new VictimsResultCache();%0A%0A        %7D catch (VictimsException e) %7B%0A            result.append(%22VictimsException while opening the database:%5Cn%22);%0A            e.printStackTrace();%0A            return result.append(e.toString()).append(%22%5Cn%22).toString();%0A        %7D%0A%0A        result.append(checkOne(db, cache, fileName, body));%0A%0A
         result.a

include key size in results