/**
 * 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.List;
import java.util.Map;

import com.box.boxjavalibv2.dao.BoxCollection;
import com.box.boxjavalibv2.dao.BoxFolder;
import com.box.boxjavalibv2.dao.BoxSharedLinkAccess;
import com.box.boxjavalibv2.jsonentities.BoxSharedLinkRequestEntity;
import com.box.boxjavalibv2.requests.requestobjects.BoxFolderDeleteRequestObject;
import com.box.boxjavalibv2.requests.requestobjects.BoxFolderRequestObject;
import com.box.boxjavalibv2.requests.requestobjects.BoxItemCopyRequestObject;
import com.box.boxjavalibv2.requests.requestobjects.BoxSharedLinkRequestObject;
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.IBoxFoldersManager APIs.
 */
public class IBoxFoldersManagerIntegrationTest extends AbstractBoxTestSupport {

    private static final Logger LOG = LoggerFactory.getLogger(IBoxFoldersManagerIntegrationTest.class);
    private static final String CAMEL_TEST_FOLDER = "CamelTestFolder";
    private static final String CAMEL_TEST_COPY_FOLDER = IBoxFoldersManagerIntegrationTest.CAMEL_TEST_FOLDER + "_Copy";
    private static final String PATH_PREFIX = BoxApiName.FOLDERS.getName();

    @Test
    // also tests create folder, and delete folder
    public void testCopyFolder() throws Exception {
        // create a test folder to copy
        final BoxFolder testFolder = createFolder();

        try {
            final Map<String, Object> headers = new HashMap<String, Object>();
            // parameter type is String
            headers.put("CamelBox.folderId", testFolder.getId());
            // parameter type is com.box.boxjavalibv2.requests.requestobjects.BoxItemCopyRequestObject
            final BoxItemCopyRequestObject requestObject = BoxItemCopyRequestObject.copyItemRequestObject("0");
            requestObject.setName(CAMEL_TEST_COPY_FOLDER);
            headers.put("CamelBox.itemCopyRequest", requestObject);

            BoxFolder result = requestBodyAndHeaders("direct://COPYFOLDER", null, headers);
            assertNotNull("copyFolder result", result);
            assertEquals("copyFolder folder name", CAMEL_TEST_COPY_FOLDER, result.getName());
            LOG.debug("copyFolder: " + result);

            // delete the copy
            deleteFolder(result.getId());
        } finally {
            deleteFolder(testFolder.getId());
        }
    }

    private BoxFolder createFolder() {
        // using com.box.boxjavalibv2.requests.requestobjects.BoxFolderRequestObject message body for single parameter "folderRequest"
        final BoxFolderRequestObject camelTestFolder = BoxFolderRequestObject.createFolderRequestObject(CAMEL_TEST_FOLDER, "0");

        BoxFolder result = requestBody("direct://CREATEFOLDER", camelTestFolder);
        assertNotNull("createFolder result", result);
        assertNotNull("createFolder folder id", result.getId());
        return result;
    }

    @Test
    public void testCreateSharedLink() throws Exception {
        final BoxFolder testFolder = createFolder();

        try {
            final Map<String, Object> headers = new HashMap<String, Object>();
            // parameter type is String
            headers.put("CamelBox.folderId", testFolder.getId());
            // parameter type is com.box.boxjavalibv2.requests.requestobjects.BoxSharedLinkRequestObject
            final BoxSharedLinkRequestEntity sharedLink = new BoxSharedLinkRequestEntity(
                    BoxSharedLinkAccess.COLLABORATORS);
            headers.put("CamelBox.sharedLinkRequest",
                    BoxSharedLinkRequestObject.createSharedLinkRequestObject(sharedLink));

            BoxFolder result = requestBodyAndHeaders("direct://CREATESHAREDLINK", null, headers);
            assertNotNull("createSharedLink result", result);
            assertNotNull("createSharedLink result", result.getSharedLink());
            LOG.debug("createSharedLink: " + result);
        } finally {
            deleteFolder(testFolder.getId());
        }
    }

    public void deleteFolder(String folderId) throws Exception {
        final Map<String, Object> headers = new HashMap<String, Object>();
        // parameter type is String
        headers.put("CamelBox.folderId", folderId);
        // parameter type is com.box.boxjavalibv2.requests.requestobjects.BoxFolderDeleteRequestObject
        headers.put("CamelBox.folderDeleteRequest", BoxFolderDeleteRequestObject.deleteFolderRequestObject(true));

        requestBodyAndHeaders("direct://DELETEFOLDER", null, headers);

        // wait for the delete to happen
        Thread.sleep(2000);
    }

    @Test
    public void testGetFolder() {
        final Map<String, Object> headers = new HashMap<String, Object>();
        // parameter type is String
        headers.put("CamelBox.folderId", "0");
        // parameter type is com.box.restclientv2.requestsbase.BoxDefaultRequestObject
//        headers.put("CamelBox.defaultRequest", null);

        final BoxFolder result = (BoxFolder) requestBodyAndHeaders("direct://GETFOLDER", null, headers);
        assertNotNull("getFolder result", result);
        assertEquals("getFolder folder id", "0", result.getId());
        LOG.debug("getFolder: " + result);
    }

    @Test
    public void testGetFolderCollaborations() throws Exception {
        final BoxFolder testFolder = createFolder();

        try {
            final Map<String, Object> headers = new HashMap<String, Object>();
            // parameter type is String
            headers.put("CamelBox.folderId", testFolder.getId());
            // parameter type is com.box.restclientv2.requestsbase.BoxDefaultRequestObject
//            headers.put("CamelBox.defaultRequest", null);

            List result = requestBodyAndHeaders("direct://GETFOLDERCOLLABORATIONS", null, headers);
            assertNotNull("getFolderCollaborations result", result);
            LOG.debug("getFolderCollaborations: " + result);
        } finally {
            deleteFolder(testFolder.getId());
        }
    }

    @Test
    public void testGetFolderItems() throws Exception {
        final Map<String, Object> headers = new HashMap<String, Object>();
        // parameter type is String
        headers.put("CamelBox.folderId", "0");
        // parameter type is com.box.boxjavalibv2.requests.requestobjects.BoxPagingRequestObject
        headers.put("CamelBox.pagingRequest", BOX_PAGING_REQUEST_OBJECT);

        BoxCollection result = requestBodyAndHeaders("direct://GETFOLDERITEMS", null, headers);
        assertNotNull(result);
        LOG.debug("getFolderItems: " + result);
    }

    @Test
    public void testUpdateFolderInfo() throws Exception {
        // create test folder
        final BoxFolder testFolder = createFolder();

        try {

            final Map<String, Object> headers = new HashMap<String, Object>();
            // parameter type is String
            headers.put("CamelBox.folderId", testFolder.getId());
            // parameter type is com.box.boxjavalibv2.requests.requestobjects.BoxFolderRequestObject
            final BoxFolderRequestObject folderRequestObject = BoxFolderRequestObject.getRequestObject();
            folderRequestObject.setTags(new String[]{CAMEL_TEST_TAG});
            folderRequestObject.setName(CAMEL_TEST_COPY_FOLDER);
            headers.put("CamelBox.folderRequest", folderRequestObject);

            BoxFolder result = requestBodyAndHeaders("direct://UPDATEFOLDERINFO", null, headers);
            assertNotNull("updateFolderInfo result", result);
            assertEquals("updateFolderInfo folder name", CAMEL_TEST_COPY_FOLDER, result.getName());
//            assertEquals("updateFolderInfo result", "["+ CAMEL_TEST_TAG + "]", Arrays.toString(result.getTags()));
            LOG.debug("updateFolderInfo: " + result);
        } finally {
            deleteFolder(testFolder.getId());
        }
    }

    @Override
    protected RouteBuilder createRouteBuilder() throws Exception {
        return new RouteBuilder() {
            public void configure() {
                // test route for copyFolder
                from("direct://COPYFOLDER")
                        .to("box://" + PATH_PREFIX + "/copyFolder");

                // test route for createFolder
                from("direct://CREATEFOLDER")
                        .to("box://" + PATH_PREFIX + "/createFolder?inBody=folderRequest");

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

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

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

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

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

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

            }
        };
    }
}
