/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.camel.component.jclouds;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.camel.EndpointInject;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.test.spring.CamelSpringTestSupport;
import org.jclouds.ContextBuilder;
import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.BlobStoreContext;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class JcloudsSpringBlobstoreTest extends CamelSpringTestSupport {

    @EndpointInject("mock:result-foo")
    protected MockEndpoint resultFoo;

    @EndpointInject("mock:result-bar")
    protected MockEndpoint resultBar;

    @BeforeClass
    public static void setUpClass() throws Exception {
        BlobStore blobStore = ContextBuilder.newBuilder("transient").credentials("id", "credential").buildView(BlobStoreContext.class).getBlobStore();
        blobStore.createContainerInLocation(null, "foo");
        blobStore.createContainerInLocation(null, "bar");
    }

    @Override
    protected AbstractApplicationContext createApplicationContext() {
        return new ClassPathXmlApplicationContext("classpath:blobstore-test.xml");
    }

    @Test
    public void testBlobStorePut() throws InterruptedException {
        resultFoo.expectedMessageCount(1);
        template.sendBody("direct:start", "Some message");
        resultFoo.assertIsSatisfied();
    }

    @Test
    public void testBlobStoreGet() throws InterruptedException {
        resultFoo.expectedMessageCount(1);
        template.sendBody("direct:start", "Some message");
        resultFoo.assertIsSatisfied();
    }

    @Test
    public void testProduceWithUrlParametes() throws InterruptedException {
        resultBar.expectedMessageCount(1);
        template.sendBody("direct:start-with-url-parameters", "Some message");
        resultBar.assertIsSatisfied();
    }
    
    @Test
    public void testBlobStoreCount() throws InterruptedException {
        Long count = template.requestBody("direct:count", "Some message", Long.class);
        assertEquals(new Long(1), count);
    }
    
    @Test
    public void testBlobStoreRemove() throws InterruptedException {
        Long count = template.requestBody("direct:remove", "Some message", Long.class);
        assertEquals(new Long(0), count);
    }
    
    @Test
    public void testBlobStoreClear() throws InterruptedException {
        Long count = template.requestBody("direct:clear", "Some message", Long.class);
        assertEquals(new Long(0), count);
    }
    
    @Test
    public void testBlobStoreDelete() throws InterruptedException {
        Boolean result = template.requestBody("direct:delete", "Some message", Boolean.class);
        assertEquals(false, result);
    }
    
    @Test
    public void testBlobStoreContainerExists() throws InterruptedException {
        Boolean result = template.requestBody("direct:exists", "Some message", Boolean.class);
        assertEquals(true, result);
    }
    
    @Test
    public void testBlobStoreRemoveBlobs() throws InterruptedException {
        Boolean result = template.requestBody("direct:exists", "Some message", Boolean.class);
        assertEquals(true, result);
        List blobsToRemove = new ArrayList<>();
        blobsToRemove.add("testName");
        Map<String, Object> headers = new HashMap<>();
        headers.put(JcloudsConstants.OPERATION, JcloudsConstants.REMOVE_BLOBS);
        headers.put(JcloudsConstants.CONTAINER_NAME, "foo");
        headers.put(JcloudsConstants.BLOB_NAME_LIST, blobsToRemove);
        template.sendBodyAndHeaders("direct:remove-blobs", null, headers);
        Long count = template.requestBody("direct:count-after-remove-blobs", null, Long.class);
        assertEquals(new Long(0), count);
    }
}
