package dst.ass1.doc.tests;

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

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import org.bson.Document;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;

import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;

import dst.ass1.doc.EmbeddedMongo;
import dst.ass1.doc.IDocumentRepository;
import dst.ass1.doc.MockMaterial;
import dst.ass1.doc.MongoService;
import dst.ass1.jpa.util.Constants;

public class Ass1_4_1Test {

    @ClassRule
    public static EmbeddedMongo embeddedMongo = new EmbeddedMongo();

    @Rule
    public MongoService mongo = new MongoService();

    private MockMaterial m1;
    private MockMaterial m2;

    private Map<String, Object> m1Properties;
    private Map<String, Object> m2Properties;

    @Before
    public void setUp() throws Exception {
        m1 = new MockMaterial(1L, "testType");
        m2 = new MockMaterial(2L, "testType2");

        m1Properties = new HashMap<>();
        m1Properties.put("1337", "7331");
        m1Properties.put("Foo", "Bar");
        m1Properties.put("Complex", Arrays.asList(1, 2, 3, 5, 8));

        m2Properties = new HashMap<>();
        m2Properties.put("123456", "654321");
        m2Properties.put("F00", "B@r");
        m2Properties.put("Complex2", Arrays.asList(4, 6, 7, 9));
    }

    @Test
    public void insert_insertsDocumentsCorrectly() throws Exception {
        IDocumentRepository documentRepository = mongo.getDocumentRepository();
        MongoDatabase mongoDatabase = mongo.getMongoDatabase();

        documentRepository.insert(m1, m1Properties);
        documentRepository.insert(m2, m2Properties);

        MongoCollection<Document> collection = mongoDatabase.getCollection(Constants.COLL_MATERIAL_DATA);
        Map<Long, Document> map = MongoService.idMap(collection, d -> d.getLong(Constants.I_MATERIAL));

        assertNotNull(map);
        assertEquals(2, map.size());

        Document document1 = map.get(1L);
        assertEquals(1L, document1.get(Constants.I_MATERIAL));
        assertEquals("testType", document1.get(Constants.M_MATERIAL_TYPE));
        assertEquals("7331", document1.get("1337"));
        assertEquals("Bar", document1.get("Foo"));
        assertEquals(Arrays.asList(1, 2, 3, 5, 8), document1.get("Complex"));

        Document document2 = map.get(2L);
        assertEquals(2L, document2.get(Constants.I_MATERIAL));
        assertEquals("testType2", document2.get(Constants.M_MATERIAL_TYPE));
        assertEquals("654321", document2.get("123456"));
        assertEquals("B@r", document2.get("F00"));
        assertEquals(Arrays.asList(4, 6, 7, 9), document2.get("Complex2"));
    }

}
