/**
 * 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.
 */

/*
 * Camel Api Route test generated by camel-component-util-maven-plugin
 * Generated on: Tue Jun 24 22:42:08 PDT 2014
 */
package org.apache.camel.component.box;

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

import com.box.boxjavalibv2.dao.BoxComment;
import com.box.boxjavalibv2.dao.BoxResourceType;
import com.box.boxjavalibv2.requests.requestobjects.BoxCommentRequestObject;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.box.internal.BoxApiName;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Test class for com.box.boxjavalibv2.resourcemanagers.IBoxCommentsManager APIs.
 */
public class IBoxCommentsManagerIntegrationTest extends AbstractBoxTestSupport {

    private static final Logger LOG = LoggerFactory.getLogger(IBoxCommentsManagerIntegrationTest.class);
    private static final String PATH_PREFIX = BoxApiName.COMMENTS.getName();

    private BoxComment addComment() throws InterruptedException {
        final BoxCommentRequestObject requestObject =
                BoxCommentRequestObject.addCommentRequestObject(BoxResourceType.FILE, testFileId, "Camel was here!");

        BoxComment result = requestBody("direct://ADDCOMMENT", requestObject);
        assertNotNull("addComment result", result);
        Thread.sleep(2000);
        return result;
    }

    @Test
    public void testAddComment1() throws Exception {
        final Map<String, Object> headers = new HashMap<String, Object>();
        // parameter type is String
        headers.put("CamelBox.commentedItemId", testFileId);
        // parameter type is com.box.boxjavalibv2.dao.IBoxType
        headers.put("CamelBox.commentedItemType", BoxResourceType.FILE);
        // parameter type is String
        headers.put("CamelBox.message", "Camel was here!");

        BoxComment result = requestBodyAndHeaders("direct://ADDCOMMENT_1", null, headers);
        assertNotNull("addComment result", result);
        LOG.debug("addComment: " + result);

        deleteComment(result.getId());
    }

    public void deleteComment(String commentId) throws Exception {
        final Map<String, Object> headers = new HashMap<String, Object>();
        // parameter type is String
        headers.put("CamelBox.commentId", commentId);
        // parameter type is com.box.restclientv2.requestsbase.BoxDefaultRequestObject
//        headers.put("CamelBox.defaultRequest", null);
        requestBodyAndHeaders("direct://DELETECOMMENT", null, headers);
    }

    @Test
    public void testGetComment() throws Exception {
        final BoxComment comment = addComment();
        try {
            final Map<String, Object> headers = new HashMap<String, Object>();
            // parameter type is String
            headers.put("CamelBox.commentId", comment.getId());
            // parameter type is com.box.restclientv2.requestsbase.BoxDefaultRequestObject
//            headers.put("CamelBox.defaultRequest", null);
            BoxComment result = requestBodyAndHeaders("direct://GETCOMMENT", null, headers);

            LOG.debug("getComment: " + result);
        } finally {
            deleteComment(comment.getId());
        }
    }

    @Test
    public void testUpdateComment() throws Exception {
        final BoxComment comment = addComment();
        try {
            final Map<String, Object> headers = new HashMap<String, Object>();
            // parameter type is String
            headers.put("CamelBox.commentId", comment.getId());
            // parameter type is com.box.boxjavalibv2.requests.requestobjects.BoxCommentRequestObject
            final BoxCommentRequestObject requestObject =
                    BoxCommentRequestObject.updateCommentRequestObject("Camel was here, again!");
            headers.put("CamelBox.commentRequest", requestObject);
            BoxComment result = requestBodyAndHeaders("direct://UPDATECOMMENT", null, headers);

            LOG.debug("updateComment: " + result);
        } finally {
            deleteComment(comment.getId());
        }
    }

    @Override
    protected RouteBuilder createRouteBuilder() throws Exception {
        return new RouteBuilder() {
            public void configure() {
                // test route for addComment
                from("direct://ADDCOMMENT")
                        .to("box://" + PATH_PREFIX + "/addComment?inBody=commentRequest");

                // test route for addComment
                from("direct://ADDCOMMENT_1")
                        .to("box://" + PATH_PREFIX + "/addComment");

                // test route for deleteComment
                from("direct://DELETECOMMENT")
                        .to("box://" + PATH_PREFIX + "/deleteComment");

                // test route for getComment
                from("direct://GETCOMMENT")
                        .to("box://" + PATH_PREFIX + "/getComment");

                // test route for updateComment
                from("direct://UPDATECOMMENT")
                        .to("box://" + PATH_PREFIX + "/updateComment");

            }
        };
    }
}
