package com.redhat.victims;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashSet;

import org.apache.commons.io.FileUtils;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

import com.redhat.victims.VictimsService.RecordStream;
import com.redhat.victims.database.VictimsDB;
import com.redhat.victims.database.VictimsDBInterface;
import com.redhat.victims.fingerprint.Algorithms;
import com.redhat.victims.mock.MockEnvironment;

public class VictimsDatabaseTest {

    private static VictimsDBInterface vdb;

    @BeforeClass
    public static void setUp() throws IOException, VictimsException {
        File updateResponse = new File(Resources.TEST_RESPONSE);
        MockEnvironment.setUp(updateResponse, null);
        sync();
    }

    @AfterClass
    public static void tearDown() {
        MockEnvironment.tearDown();
    }

    public static void sync() throws VictimsException {
        vdb = VictimsDB.db();
        vdb.synchronize();
    }

    @Test
    public void testSynchronize() throws VictimsException, IOException {
        String sha512 = FileUtils.readFileToString(
                new File(Resources.TEST_SHA512)).trim();
        String cve = FileUtils.readFileToString(new File(Resources.TEST_CVE))
                .trim();
        assertTrue("Synchronized DB does not contain expected hash.", vdb
                .getVulnerabilities(sha512).contains(cve));
    }

    private HashSet<String> getVulnerabilities(VictimsDBInterface vdb,
            VictimsRecord vr) throws VictimsException {
        return vdb.getVulnerabilities(vr);
    }

    private void testVulnerabilities(VictimsDBInterface vdb, boolean embedded)
            throws IOException, VictimsException {
        FileInputStream fin = new FileInputStream(Resources.TEST_RESPONSE);
        RecordStream rs = new RecordStream(fin);
        VictimsRecord vr;
        while (rs.hasNext()) {
            vr = rs.getNext();
            if (vr.getHashes(Algorithms.SHA512).size() > 0) {
                HashSet<String> cves = getVulnerabilities(vdb, vr);
                vr.hash = "0";
                if (embedded) {
                    // since we are testing for embedded, inject some new
                    // filehashes to simulate a superset
                    vr.getHashes(Algorithms.SHA512).put("1", "1");
                    vr.getHashes(Algorithms.SHA512).put("2", "2");
                }
                HashSet<String> result = getVulnerabilities(vdb, vr);
                assertEquals("Unexpected number of CVEs", cves.size(),
                        result.size());
                for (String cve : cves) {
                    assertTrue(String.format(
                            "%s was expected, but was not found in result.",
                            cve), result.contains(cve));
                }
                break;
            }
        }
    }

    @Test
    public void testVulnerabilities() throws IOException, VictimsException {
        testVulnerabilities(vdb, false);
    }

    @Test
    public void testEmbeddedVulnerabilities() throws IOException,
            VictimsException {
        testVulnerabilities(vdb, true);
    }

    @Test
    public void testResync() throws VictimsException {
        VictimsDBInterface vdb = VictimsDB.db();
        vdb.synchronize();
    }

    @Test(expected = VictimsException.class)
    public void testDerby() throws IOException, VictimsException {
        String old = System.getProperty(VictimsConfig.Key.DB_DRIVER);
        try {
            System.setProperty(VictimsConfig.Key.DB_DRIVER,
                    "org.apache.derby.jdbc.EmbeddedDriver");
            VictimsDBInterface vdb = VictimsDB.db();
            vdb.synchronize();
        } finally {
            if (old != null) {
                System.setProperty(VictimsConfig.Key.DB_DRIVER, old);
            } else {
                System.clearProperty(VictimsConfig.Key.DB_DRIVER);
            }
        }

    }
}

@@ -1810,16 +1810,30 @@
 embedded
+, boolean meta
 )%0A      
@@ -2212,32 +2212,210 @@
 ities(vdb, vr);%0A
+                HashSet%3CString%3E result;%0A%0A                if (meta) %7B%0A                    result = vdb.getVulnerabilities(vr.getFlattenedMetaData());%0A                %7D else %7B%0A    
                 
@@ -2441,24 +2441,28 @@
             
+ 
+   
 if (embedded
@@ -2461,24 +2461,28 @@
 embedded) %7B%0A
+    
             
@@ -2563,16 +2563,20 @@
         
+    
 // fileh
@@ -2604,16 +2604,20 @@
 uperset%0A
+    
         
@@ -2687,32 +2687,36 @@
                 
+    
 vr.getHashes(Alg
@@ -2754,32 +2754,36 @@
                 
+    
 %7D%0A              
@@ -2780,39 +2780,27 @@
             
-HashSet%3CString%3E
+   
  result = ge
@@ -2818,32 +2818,50 @@
 ities(vdb, vr);%0A
+                %7D%0A
                 
@@ -3368,16 +3368,23 @@
 ies(vdb,
+ false,
  false);
@@ -3530,16 +3530,172 @@
 ies(vdb,
+ true, false);%0A    %7D%0A%0A    @Test%0A    public void testPropertyVulnerabilities() throws IOException, VictimsException %7B%0A        testVulnerabilities(vdb, false,
  true);%0A

Add test case for porperty matching