/*
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package com.celements.pagetype.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.xwiki.component.annotation.Component;
import org.xwiki.component.annotation.Requirement;

import com.celements.pagetype.IPageTypeConfig;
import com.celements.pagetype.IPageTypeProviderRole;
import com.celements.pagetype.PageTypeReference;

@Component
public class PageTypeService implements IPageTypeRole {

  @Requirement
  Map<String, IPageTypeProviderRole> pageTypeProviders;

  public IPageTypeConfig getPageTypeConfig(String pageTypeName) {
    PageTypeReference pageTypeRef = getPageTypeRefsByConfigNames().get(pageTypeName);
    return getProviderForPageTypeRef(pageTypeRef).getPageTypeByReference(pageTypeRef);
  }

  private IPageTypeProviderRole getProviderForPageTypeRef(PageTypeReference pageTypeRef) {
    return pageTypeProviders.get(pageTypeRef.getProviderHint());
  }

  public List<String> getPageTypesConfigNamesForCategories(Set<String> catList,
      boolean onlyVisible) {
    List<String> pageTypeConfigNameList = new ArrayList<String>();
    for (PageTypeReference pageTypeRef : getPageTypeRefsForCategories(catList,
        onlyVisible)) {
      pageTypeConfigNameList.add(pageTypeRef.getConfigName());
    }
    return pageTypeConfigNameList;
  }

  public List<PageTypeReference> getPageTypeRefsForCategories(Set<String> catList,
      boolean onlyVisible) {
    if (onlyVisible) {
      Set<PageTypeReference> visiblePTSet = new HashSet<PageTypeReference>();
      for (PageTypeReference pageTypeRef : getPageTypeRefsForCategories(catList)) {
        if (getProviderForPageTypeRef(pageTypeRef).getPageTypeByReference(pageTypeRef
            ).isVisible()) {
          visiblePTSet.add(pageTypeRef);
        }
      }
      return new ArrayList<PageTypeReference>(visiblePTSet);
    } else {
      return new ArrayList<PageTypeReference>(getPageTypeRefsForCategories(catList));
    }
  }

  Map<String, PageTypeReference> getPageTypeRefsByConfigNames() {
    Map<String, PageTypeReference> pageTypeRefsMap =
      new HashMap<String, PageTypeReference>();
    for (PageTypeReference pageTypeRef : getAllPageTypeRefs()) {
      pageTypeRefsMap.put(pageTypeRef.getConfigName(), pageTypeRef);
    }
    return pageTypeRefsMap;
  }

  private Set<PageTypeReference> getAllPageTypeRefs() {
    HashSet<PageTypeReference> pageTypeRefSet = new HashSet<PageTypeReference>();
    for (IPageTypeProviderRole pageTypeProvider : pageTypeProviders.values()) {
      for (PageTypeReference pageTypeRef : pageTypeProvider.getPageTypes()) {
        pageTypeRefSet.add(pageTypeRef);
      }
    }
    return pageTypeRefSet;
  }

  private Set<PageTypeReference> getPageTypeRefsForCategories(Set<String> catList) {
    catList = new HashSet<String>(catList);
    Set<PageTypeReference> filteredPTset = new HashSet<PageTypeReference>();
    for (PageTypeReference pageTypeRef : getAllPageTypeRefs()) {
      for (String category : pageTypeRef.getCategories()) {
        if (catList.contains(category)) {
          filteredPTset.add(pageTypeRef);
        }
      }
    }
    return filteredPTset;
  }

}

@@ -952,24 +952,49 @@
 .ArrayList;%0A
+import java.util.Arrays;%0A
 import java.
@@ -1003,24 +1003,24 @@
 il.HashMap;%0A
-
 import java.
@@ -1097,24 +1097,109 @@
 .util.Set;%0A%0A
+import org.apache.commons.logging.Log;%0Aimport org.apache.commons.logging.LogFactory;%0A
 import org.x
@@ -1505,16 +1505,107 @@
 Role %7B%0A%0A
+  private static Log LOGGER = LogFactory.getFactory().getInstance(PageTypeService.class);%0A%0A
   @Requi
@@ -2413,32 +2413,164 @@
 gName());%0A    %7D%0A
+    LOGGER.debug(%22getPageTypesConfigNamesForCategories: return %22 + Arrays.deepToString(%0A        pageTypeConfigNameList.toArray()));%0A
     return pageT
@@ -3060,24 +3060,251 @@
   %7D%0A      %7D%0A
+      LOGGER.debug(%22getPageTypeRefsForCategories: for catList %5B%22 + Arrays.deepToString(%0A          catList.toArray()) + %22%5D and onlyVisible %5B%22 + onlyVisible + %22%5D return %22%0A          + Arrays.deepToString(visiblePTSet.toArray()));%0A
       return
@@ -4145,32 +4145,138 @@
 ;%0A      %7D%0A    %7D%0A
+    LOGGER.debug(%22getAllPageTypeRefs: return %22 + Arrays.deepToString(%0A        pageTypeRefSet.toArray()));%0A
     return pageT
@@ -4720,30 +4720,206 @@
   %7D%0A      %7D%0A
-
     %7D%0A
+    LOGGER.debug(%22getPageTypeRefsForCategories: for catList %5B%22 + Arrays.deepToString(%0A        catList.toArray()) + %22%5D return %22 + Arrays.deepToString(filteredPTset.toArray()));%0A
     return f

add logging to PageTypeService