package org.bricolages.streaming.s3;
import org.bricolages.streaming.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.*;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.Arrays;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
import lombok.*;

@DataJpaTest
@RunWith(SpringJUnit4ClassRunner.class)
public class ObjectMapperTest {
    ObjectMapper newMapper(ObjectMapper.Entry... entries) {
        return new ObjectMapper(Arrays.asList(entries));
    }

    ObjectMapper.Entry entry(String srcUrlPattern, String streamName, String streamPrefix, String destBucket, String destPrefix, String objectPrefix, String objectName) {
        return new ObjectMapper.Entry(srcUrlPattern, streamName, streamPrefix, destBucket, destPrefix, objectPrefix, objectName);
    }

    S3ObjectLocation loc(String url) throws S3UrlParseException {
        return S3ObjectLocation.forUrl(url);
    }

    @Test
    public void mapByPatterns() throws Exception {
        val map = newMapper(entry("s3://src-bucket/src-prefix/(schema\\.table)/(.*\\.gz)", "$1", "src-prefix", "dest-bucket", "dest-prefix/$1", "", "$2"));
        map.check();
        val result = map.mapByPatterns("s3://src-bucket/src-prefix/schema.table/datafile.json.gz");
        assertEquals(loc("s3://dest-bucket/dest-prefix/schema.table/datafile.json.gz"), result.getDestLocation());
        assertEquals("schema.table", result.getStreamName());
        assertNull(map.mapByPatterns("s3://src-bucket-2/src-prefix/schema.table/datafile.json.gz"));
    }

    @Test
    public void map_localfile() throws Exception {
        val map = newMapper(entry("file:/(?:.+/)?src-bucket/src-prefix/(schema\\.table)/(.*\\.gz)", "$1", "src-prefix", "dest-bucket", "dest-prefix/$1", "", "$2"));
        map.check();
        val result = map.mapByPatterns("file:/path/to/src-bucket/src-prefix/schema.table/datafile.json.gz");
        assertEquals(loc("s3://dest-bucket/dest-prefix/schema.table/datafile.json.gz"), result.getDestLocation());
        assertEquals("schema.table", result.getStreamName());
        assertNull(map.mapByPatterns("s3://src-bucket-2/src-prefix/schema.table/datafile.json.gz"));
    }
    
    @Test(expected=ConfigError.class)
    public void map_baddest() throws Exception {
        val map = newMapper(entry("s3://src-bucket/src-prefix/(schema\\.table)/(.*\\.gz)", "$3", "src-prefix", "dest-bucket", "dest-prefix/$1", "", "$2"));
        map.check();
        map.mapByPatterns("s3://src-bucket/src-prefix/schema.table/datafile.json.gz");
    }

    @Test(expected=ConfigError.class)
    public void map_badregex() throws Exception {
        val map = newMapper(entry("****", "$1", "src-prefix", "dest-bucket", "dest-prefix/$1", "", "$2"));
        map.check();
    }

    @Autowired TestEntityManager entityManager;
    @Autowired DataStreamRepository streamRepos;
    @Autowired StreamBundleRepository bundleRepos;

    @Test
    public void map() throws Exception {
        entityManager.persist(new DataStream("schema.table"));
        DataStream stream = streamRepos.findStream("schema.table");
        entityManager.persist(new StreamBundle(stream, "src-bucket", "src-prefix", "dest-bucket-2", "dest-prefix-2"));
        StreamBundle bundle = bundleRepos.findStreamBundle("src-bucket", "src-prefix");
        assertNotNull(bundle.getId());
        assertEquals("src-bucket", bundle.getBucket());
    }
}

@@ -500,20 +500,20 @@
 pper new
-Mapp
+Rout
 er(Objec
@@ -540,38 +540,44 @@
 ries) %7B%0A        
-return
+val router =
  new ObjectMappe
@@ -599,24 +599,137 @@
 (entries));%0A
+        router.streamRepos = streamRepos;%0A        router.streamBundleRepos = bundleRepos;%0A        return router;%0A
     %7D%0A%0A    O
@@ -1223,36 +1223,36 @@
    val map = new
-Mapp
+Rout
 er(entry(%22s3://s
@@ -1846,36 +1846,36 @@
    val map = new
-Mapp
+Rout
 er(entry(%22file:/
@@ -2517,36 +2517,36 @@
    val map = new
-Mapp
+Rout
 er(entry(%22s3://s
@@ -2884,20 +2884,20 @@
 ap = new
-Mapp
+Rout
 er(entry
@@ -3269,26 +3269,19 @@
         
-DataStream
+val
  stream 
@@ -3380,32 +3380,34 @@
 eam, %22src-bucket
+-2
 %22, %22src-prefix%22,
@@ -3396,32 +3396,34 @@
 -2%22, %22src-prefix
+-2
 %22, %22dest-bucket-
@@ -3453,28 +3453,19 @@
         
-StreamBundle
+val
  bundle 
@@ -3502,24 +3502,26 @@
 (%22src-bucket
+-2
 %22, %22src-pref
@@ -3522,28 +3522,31 @@
 c-prefix
+-2
 %22);%0A
+%0A
         
 assertNo
@@ -3541,91 +3541,661 @@
     
-assertNotNull(bundle.getId());%0A        assertEquals(%22src-bucket%22, bundle.getBucket(
+val router = newRouter(entry(%22file:/(?:.+/)?src-bucket/src-prefix/(schema%5C%5C.table)/(.*%5C%5C.gz)%22, %22$1%22, %22src-prefix%22, %22dest-bucket%22, %22dest-prefix/$1%22, %22%22, %22$2%22));%0A        router.check();%0A%0A        val result = router.map(loc(%22s3://src-bucket-2/src-prefix-2/schema.table/datafile.json.gz%22));%0A        assertEquals(loc(%22s3://dest-bucket-2/dest-prefix-2/schema.table/datafile.json.gz%22), result.getDestLocation());%0A        assertEquals(%22schema.table%22, result.getStreamName());%0A%0A        assertNull(router.map(loc(%22s3://src-bucket-UNKNOWN/src-prefix-UNKNOWN/schema.table/datafile.json.gz%22)));%0A        assertNull(router.map(loc(%22s3://src-bucket-2/datafile.json.gz%22)
 ));%0A

test ObjectMapper.map