/*
 * Copyright 2015 Hewlett-Packard Development Company, L.P.
 * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
 */

package com.hp.autonomy.iod.client.textindexing;

import com.hp.autonomy.iod.client.AbstractIodClientIntegrationTest;
import com.hp.autonomy.iod.client.error.IodErrorCode;
import com.hp.autonomy.iod.client.error.IodErrorException;
import com.hp.autonomy.iod.client.job.IodJobCallback;
import lombok.extern.slf4j.Slf4j;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import retrofit.mime.TypedFile;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CountDownLatch;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasSize;

@Slf4j
public class AddToTextIndexServiceITCase extends AbstractIodClientIntegrationTest {

    private static final String REFERENCE = "3ac70cc2-606e-486a-97d0-511e762b2183";

    private AddToTextIndexServiceImpl addToTextIndexService;

    @Override
    @Before
    public void setUp() {
        super.setUp();

        addToTextIndexService = new AddToTextIndexServiceImpl(getRestAdapter().create(AddToTextIndexService.class));
    }

    @After
    public void tearDown() {
        addToTextIndexService.destroy();
    }

    @Test
    public void testAddJsonToTextIndex() throws IodErrorException, InterruptedException {
        final Document document = new Document.Builder()
                .setReference(REFERENCE)
                .setTitle("TEST DOCUMENT")
                .setContent("I heartily endorse this event or product")
                .addField("coolstuff", "This is so cool!")
                .build();

        final Map<String, Object> params = new AddToTextIndexRequestBuilder()
                .setDuplicateMode(AddToTextIndexRequestBuilder.DuplicateMode.replace)
                .build();

        final CountDownLatch latch = new CountDownLatch(1);
        final TestCallback callback = new TestCallback(latch);

        addToTextIndexService.addJsonToTextIndex(getApiKey(), new Documents<>(document), getIndex(), params, callback);

        latch.await();

        final AddToTextIndexResponse result = callback.result;

        assertThat(result, is(notNullValue()));
        assertThat(result.getIndex(), is(getIndex()));
        assertThat(result.getReferences(), hasSize(1));

        final AddToTextIndexReference referenceObject = result.getReferences().get(0);

        assertThat(referenceObject.getReference(), is(REFERENCE));
    }

    @Test
    public void testAddFileToTextIndex() throws IodErrorException, InterruptedException {
        final TypedFile file = new TypedFile("text/plain", new File("src/test/resources/com/hp/autonomy/iod/client/textindexing/the-end.txt"));
        final String reference = "63edb67f-c930-4b7b-8c33-2cd28e5cc670";

        final Map<String, Object> additionalMetadata = new HashMap<>();
        additionalMetadata.put("reference", reference);
        additionalMetadata.put("title", "The End");

        final Map<String, Object> params = new AddToTextIndexRequestBuilder()
                .setDuplicateMode(AddToTextIndexRequestBuilder.DuplicateMode.replace)
                .addAdditionalMetadata(additionalMetadata)
                .build();

        final CountDownLatch latch = new CountDownLatch(1);
        final TestCallback callback = new TestCallback(latch);

        addToTextIndexService.addFileToTextIndex(getApiKey(), file, getIndex(), params, callback);

        latch.await();

        final AddToTextIndexResponse result = callback.result;

        assertThat(result, is(notNullValue()));
        assertThat(result.getIndex(), is(getIndex()));
        assertThat(result.getReferences(), hasSize(1));

        final AddToTextIndexReference referenceObject = result.getReferences().get(0);

        assertThat(referenceObject.getReference(), is(reference));
    }

    private static class TestCallback implements IodJobCallback<AddToTextIndexResponse> {

        private final CountDownLatch latch;

        private volatile AddToTextIndexResponse result;

        public TestCallback(final CountDownLatch latch) {
            this.latch = latch;
        }

        @Override
        public void success(final AddToTextIndexResponse result) {
            log.debug("Result from IDOL OnDemand: {}", result);

            this.result = result;

            latch.countDown();
        }

        @Override
        public void error(final IodErrorCode error) {
            log.error("Error code " + error + " returned from IDOL OnDemand");

            latch.countDown();
        }

        @Override
        public void handleException(final RuntimeException exception) {
            log.error("Runtime exception thrown", exception);

            latch.countDown();
        }
    }

}

@@ -299,62 +299,8 @@
 st;%0A
-import com.hp.autonomy.iod.client.error.IodErrorCode;%0A
 impo
@@ -392,18 +392,17 @@
 ent.
-job.IodJob
+util.Test
 Call
@@ -2052,32 +2052,56 @@
 nal TestCallback
+%3CAddToTextIndexResponse%3E
  callback = new 
@@ -2104,32 +2104,34 @@
 new TestCallback
+%3C%3E
 (latch);%0A%0A      
@@ -2316,38 +2316,43 @@
 sult = callback.
-r
+getR
 esult
+()
 ;%0A%0A        asser
@@ -3495,16 +3495,40 @@
 Callback
+%3CAddToTextIndexResponse%3E
  callbac
@@ -3547,16 +3547,18 @@
 Callback
+%3C%3E
 (latch);
@@ -3738,22 +3738,27 @@
 allback.
-r
+getR
 esult
+()
 ;%0A%0A     
@@ -3992,32 +3992,32 @@
 nces().get(0);%0A%0A
+
         assertTh
@@ -4078,922 +4078,6 @@
  %7D%0A%0A
-    private static class TestCallback implements IodJobCallback%3CAddToTextIndexResponse%3E %7B%0A%0A        private final CountDownLatch latch;%0A%0A        private volatile AddToTextIndexResponse result;%0A%0A        public TestCallback(final CountDownLatch latch) %7B%0A            this.latch = latch;%0A        %7D%0A%0A        @Override%0A        public void success(final AddToTextIndexResponse result) %7B%0A            log.debug(%22Result from IDOL OnDemand: %7B%7D%22, result);%0A%0A            this.result = result;%0A%0A            latch.countDown();%0A        %7D%0A%0A        @Override%0A        public void error(final IodErrorCode error) %7B%0A            log.error(%22Error code %22 + error + %22 returned from IDOL OnDemand%22);%0A%0A            latch.countDown();%0A        %7D%0A%0A        @Override%0A        public void handleException(final RuntimeException exception) %7B%0A            log.error(%22Runtime exception thrown%22, exception);%0A%0A            latch.countDown();%0A        %7D%0A    %7D%0A%0A
 %7D%0A

Refactor test to use the new TestCallback