
package org.robbins.flashcards.cassandra.repository;

import com.datastax.driver.core.BatchStatement;
import com.datastax.driver.core.PreparedStatement;
import com.datastax.driver.core.RegularStatement;
import com.datastax.driver.core.Session;
import org.apache.commons.lang3.NotImplementedException;
import org.robbins.flashcards.cassandra.repository.domain.FlashCardCassandraEntity;
import org.robbins.flashcards.cassandra.repository.domain.TagCassandraEntity;
import org.robbins.flashcards.cassandra.repository.domain.TagFlashCardCassandraEntity;
import org.robbins.flashcards.repository.TagRepository;
import org.springframework.data.cassandra.core.CassandraOperations;
import org.springframework.stereotype.Repository;

import javax.inject.Inject;
import java.util.List;
import java.util.UUID;

import static com.datastax.driver.core.querybuilder.QueryBuilder.*;

@Repository
public class TagRepositoryImpl extends AbstractCrudRepositoryImpl<TagCassandraEntity, UUID> implements
        TagRepository<TagCassandraEntity, UUID> {

    @Inject
    private CassandraOperations cassandraOperations;

    @Inject
    private TagCassandraRepository repository;

    @Inject
    private TagFlashcardCassandraRepository tagFlashcardCassandraRepository;

    @Inject FlashCardCassandraRepository flashCardCassandraRepository;

    private static final String TAG_TABLE = "tag";
    private static final String FLASHCARD_TABLE = "flashcard";
    private static final String ID = "id";
    private static final String NAME = "name";
    private static final String TAGS = "tags";

    @Override
    public TagCassandraRepository getRepository() {
        return repository;
    }

    @Override
    public TagCassandraEntity save(final TagCassandraEntity tag) {
        cassandraOperations.execute(tagBatch(tag));

        return tag;
    }

    private void updateFlashCardTags(final TagCassandraEntity tag) {
        List<TagFlashCardCassandraEntity> tagFlashcards = tagFlashcardCassandraRepository.findByTagId(tag.getId());
        if (tagFlashcards != null && tagFlashcards.size() > 0) {
            for (TagFlashCardCassandraEntity tagFlashCard : tagFlashcards) {
                FlashCardCassandraEntity flashcard = flashCardCassandraRepository.findOne(tagFlashCard.getId().getFlashCardId());
                if (flashcard != null && flashcard.getTags() != null) {
                    flashcard.getTags().put(tag.getId(), tag.getName());
                }
            }
        }
    }

    private BatchStatement tagBatch(TagCassandraEntity tag) {
        Session session = cassandraOperations.getSession();

        PreparedStatement tagStatement = session.prepare(tagInsert());
        PreparedStatement flashcardStatement = session.prepare(flashcardUpdateTag());

        BatchStatement batch = new BatchStatement();

        // flashcard
        batch.add(tagStatement.bind(
                tag.getId(),
                tag.getName()));

        List<TagFlashCardCassandraEntity> tagFlashcards = tagFlashcardCassandraRepository.findByTagId(tag.getId());
        if (tagFlashcards != null && tagFlashcards.size() > 0) {
            for (TagFlashCardCassandraEntity tagFlashCard : tagFlashcards) {
                FlashCardCassandraEntity flashcard = flashCardCassandraRepository.findOne(tagFlashCard.getId().getFlashCardId());
                if (flashcard != null && flashcard.getTags() != null) {
                    batch.add(flashcardStatement.bind(
                            tag.getId(),
                            tag.getName(),
                            flashcard.getId()));
                }
            }
        }
        return batch;
    }

    private RegularStatement tagInsert() {
        return insertInto(TAG_TABLE)
                .value(ID, bindMarker())
                .value(NAME, bindMarker());
    }

    private RegularStatement flashcardUpdateTag() {
        return update(FLASHCARD_TABLE)
                .with(put(TAGS, bindMarker(), bindMarker()))
                .where(eq(ID, bindMarker()));
    }

    @Override
    public TagCassandraEntity findByName(final String name) {
        return repository.findByName(name);
    }

    @Override
    public List<TagCassandraEntity> findByFlashcards_Id(UUID flashcardId) {
        throw new NotImplementedException("method not yet implemented in Cassandra repository");
    }
}

@@ -600,16 +600,73 @@
 sitory;%0A
+import org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;%0A
 import o
@@ -725,16 +725,16 @@
 ations;%0A
-
 import o
@@ -772,24 +772,63 @@
 epository;%0A%0A
+import javax.annotation.PostConstruct;%0A
 import javax
@@ -1125,16 +1125,108 @@
 UID%3E %7B%0A%0A
+    private static final Logger LOGGER = LoggerFactory.getLogger(TagRepositoryImpl.class);%0A%0A
     @Inj
@@ -1501,24 +1501,119 @@
 epository;%0A%0A
+    private PreparedStatement tagStatement;%0A    private PreparedStatement flashcardStatement;%0A%0A
     private 
@@ -2121,456 +2121,302 @@
     
-private void updateFlashCardTags(final TagCassandraEntity tag) %7B%0A        List%3CTagFlashCardCassandraEntity%3E tagFlashcards = tagFlashcardCassandraRepository.findByTagId(tag.getId());%0A        if (tagFlashcards != null && tagFlashcards.size() %3E 0) %7B%0A            for (TagFlashCardCassandraEntity tagFlashCard : tagFlashcards) %7B%0A                FlashCardCassandraEntity flashcard = flashCardCassandraRepository.findOne(tagFlashCard.getId().getFlashCardId
+@SuppressWarnings(%22unused%22)%0A    @PostConstruct%0A    private void initStatements()%7B%0A        Session session = cassandraOperations.getSession();%0A        if (session == null)%7B%0A            LOGGER.error(%22Cassandra not available%22);%0A        %7D else %7B%0A            tagStatement = session.prepare(tagInsert
 ());
@@ -2424,32 +2424,24 @@
             
-    if (
 flashcard !=
@@ -2441,155 +2441,58 @@
 card
- != null && flashcard.getTags() != null) %7B%0A                    flashcard.getTags().put(tag.getId(), tag.getName());%0A                %7D%0A            %7D
+Statement = session.prepare(flashcardUpdateTag());
 %0A   
@@ -2494,24 +2494,25 @@
 ;%0A        %7D%0A
+%0A
     %7D%0A%0A    p
@@ -2572,227 +2572,8 @@
 ) %7B%0A
-        Session session = cassandraOperations.getSession();%0A%0A        PreparedStatement tagStatement = session.prepare(tagInsert());%0A        PreparedStatement flashcardStatement = session.prepare(flashcardUpdateTag());%0A%0A
     
@@ -2624,30 +2624,8 @@
 t();
-%0A%0A        // flashcard
 %0A   

prepare Cassandra PreparedSatements only once