/*
 * Copyright (C) 2005 - 2011 Jaspersoft Corporation. All rights reserved.
 * http://www.jaspersoft.com.
 *
 * Unless you have purchased  a commercial license agreement from Jaspersoft,
 * the following license terms  apply:
 *
 * This program is free software: you can redistribute it and/or  modify
 * it under the terms of the GNU Affero General Public License  as
 * published by the Free Software Foundation, either version 3 of  the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero  General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public  License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

package com.jaspersoft.jasperserver.search.service.impl;

import com.jaspersoft.jasperserver.api.common.domain.ExecutionContext;
import com.jaspersoft.jasperserver.api.metadata.common.domain.Resource;
import com.jaspersoft.jasperserver.api.metadata.common.domain.ResourceLookup;
import com.jaspersoft.jasperserver.api.metadata.common.service.RepositoryService;
import com.jaspersoft.jasperserver.api.search.SearchCriteriaFactory;
import com.jaspersoft.jasperserver.api.search.SearchFilter;
import com.jaspersoft.jasperserver.api.search.SearchSorter;
import com.jaspersoft.jasperserver.api.search.TransformerFactory;
import com.jaspersoft.jasperserver.search.common.ResourceDetails;
import com.jaspersoft.jasperserver.search.service.ChildrenLoaderService;
import com.jaspersoft.jasperserver.search.service.RepositorySearchService;
import com.jaspersoft.jasperserver.search.service.ResourceService;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * Implementation of {@link RepositorySearchService}.
 *
 * @author Yuriy Plakosh
 * @version $Id$
 */
public class RepositorySearchServiceImpl implements RepositorySearchService {
    private RepositoryService repositoryService;
    private ResourceService resourceService;
    private TransformerFactory transformerFactory;
    private Map<String, ChildrenLoaderService> childrenLoaders;

    public void setRepositoryService(RepositoryService repositoryService) {
        this.repositoryService = repositoryService;
    }

    public void setResourceService(ResourceService resourceService) {
        this.resourceService = resourceService;
    }

    public void setTransformerFactory(TransformerFactory transformerFactory) {
        this.transformerFactory = transformerFactory;
    }

    public List<ResourceDetails> getResults(ExecutionContext context, SearchCriteriaFactory searchCriteriaFactory,
            List<SearchFilter> filters, SearchSorter sorter, int current, int max) {
        List<ResourceLookup> resources = repositoryService.getResources(context, searchCriteriaFactory,
                filters, sorter, transformerFactory, current, max);

        return getResourceDetailsList(resources);
    }

    public int getResultsCount(ExecutionContext context, SearchCriteriaFactory searchCriteriaFactory,
           List<SearchFilter> filters, SearchSorter sorter) {
        return repositoryService.getResourcesCount(context, searchCriteriaFactory, filters, sorter, transformerFactory);
    }

    public List<ResourceDetails> getResourceChildren(String type, String resourceUri) {
        ChildrenLoaderService childrenLoaderService = childrenLoaders.get(type);

        if (childrenLoaderService != null) {
            return getResourceDetailsList(childrenLoaderService.getChildren(resourceUri));
        }

        return Collections.emptyList();
    }

    private List<ResourceDetails> getResourceDetailsList(List<ResourceLookup> resources) {
        List<ResourceDetails> list = new ArrayList<ResourceDetails>();

        for (Resource resource : resources) {
            ResourceDetails resourceDetails = resourceService.getResourceDetails(resource);

            list.add(resourceDetails);
        }

        return list;
    }

    public void setChildrenLoaders(Map<String, ChildrenLoaderService> childrenLoaders) {
        this.childrenLoaders = childrenLoaders;
    }
}
