package com.celements.menu.access;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xwiki.component.annotation.Component;
import org.xwiki.component.annotation.Requirement;
import org.xwiki.context.Execution;
import org.xwiki.model.reference.DocumentReference;

import com.celements.web.service.IWebUtilsService;
import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.XWikiException;
import com.xpn.xwiki.user.api.XWikiRightService;

@Component("celements.defaultMenuAccess")
public class DefaultMenuAccessProvider implements IMenuAccessProviderRole {

  private static Log LOGGER = LogFactory.getFactory().getInstance(
      DefaultMenuAccessProvider.class);

  @Requirement
  IWebUtilsService webUtilsService;

  @Requirement
  Execution execution;

  private XWikiContext getContext() {
    return (XWikiContext)execution.getContext().getProperty("xwikicontext");
  }

  public boolean hasview(DocumentReference menuBarDocRef
      ) throws NoAccessDefinedException, XWikiException {
    String database = getContext().getDatabase();
    getContext().setDatabase(getContext().getOriginalDatabase());
    if (webUtilsService.getRefDefaultSerializer().serialize(menuBarDocRef
        ).endsWith("Celements2.AdminMenu")) {
      LOGGER.debug("hasview: AdminMenu [" + getContext().getUser() + "] isAdvancedAdmin ["
          + webUtilsService.isAdvancedAdmin() + "].");
      return webUtilsService.isAdvancedAdmin();
    } else if (webUtilsService.getRefDefaultSerializer().serialize(menuBarDocRef
        ).endsWith("Celements2.LayoutMenu")) {
      LOGGER.debug("hasview: LayoutMenu [" + getContext().getUser() + "] isLayoutEditor ["
          + webUtilsService.isLayoutEditor() + "] isAdvancedAdmin ["
          + webUtilsService.isAdvancedAdmin() + "].");
      return webUtilsService.isLayoutEditor() || webUtilsService.isAdvancedAdmin();
    }
    getContext().setDatabase(database);
    return hasCentralAndLocalView(menuBarDocRef);
  }

  public boolean denyView(DocumentReference menuBarDocRef) {
    return false;
  }

  private boolean hasCentralAndLocalView(DocumentReference menuBarDocRef
      ) throws XWikiException {
    String database = getContext().getDatabase();
    getContext().setDatabase("celements2web");
    DocumentReference menuBar2webDocRef = new DocumentReference("celements2web",
        menuBarDocRef.getLastSpaceReference().getName(), menuBarDocRef.getName());
    String menuBar2webFullName = webUtilsService.getRefDefaultSerializer(
        ).serialize(menuBar2webDocRef);
    boolean centralView = !getContext().getWiki().exists(menuBar2webDocRef, getContext())
      || getContext().getWiki().getRightService().hasAccessLevel("view",
          getContext().getUser(), menuBar2webFullName, getContext());
    LOGGER.debug("hasview: centralView [" + menuBar2webFullName + "] for ["
        + getContext().getUser() + "] -> [" + centralView + "] on database ["
        + getContext().getDatabase() + "].");
    getContext().setDatabase(getContext().getOriginalDatabase());
    DocumentReference menuBarLocalDocRef = new DocumentReference(getContext(
        ).getOriginalDatabase(), menuBarDocRef.getLastSpaceReference().getName(),
        menuBarDocRef.getName());
    String menuBarFullName = webUtilsService.getRefDefaultSerializer().serialize(
        menuBarLocalDocRef);
    boolean localView = true;
    if (getContext().getWiki().exists(menuBarLocalDocRef, getContext())) {
      localView = getContext().getWiki().getRightService().hasAccessLevel("view",
            getContext().getUser(), menuBarFullName, getContext());
    } else if (XWikiRightService.GUEST_USER_FULLNAME.equals(getContext().getUser())) {
      String menuBarLocalFullName = webUtilsService.getRefLocalSerializer().serialize(
          menuBarLocalDocRef);
      String prefParamName = "CelMenuBar-" + menuBarLocalFullName;
      String cfgFallbackName = "celements.menubar.guestview." + menuBarLocalFullName;
      localView = (getContext().getWiki().getXWikiPreferenceAsInt(prefParamName,
          cfgFallbackName, 0, getContext()) == 1);
      LOGGER.info("hasview: localView default for quest on [" + menuBarFullName + "] -> ["
          + localView + "] on database [" + getContext().getDatabase()
          + "]. Checked prefParamName [" + prefParamName + "] and cfgFallbackName ["
          + cfgFallbackName + "].");
    }
    LOGGER.debug("hasview: localView [" + menuBarFullName + "] for ["
        + getContext().getUser() + "] -> [" + localView + "] on database ["
        + getContext().getDatabase() + "].");
    getContext().setDatabase(database);
    boolean centralAndLocalView = centralView && localView;
    return centralAndLocalView;
  }

}

@@ -1071,32 +1071,44 @@
 .getDatabase();%0A
+    try %7B%0A  
     getContext()
@@ -1153,24 +1153,26 @@
 atabase());%0A
+  
     if (webU
@@ -1233,32 +1233,34 @@
 rDocRef%0A        
+  
 ).endsWith(%22Cele
@@ -1273,32 +1273,34 @@
 .AdminMenu%22)) %7B%0A
+  
       LOGGER.deb
@@ -1376,32 +1376,34 @@
 in %5B%22%0A          
+  
 + webUtilsServic
@@ -1429,32 +1429,34 @@
  + %22%5D.%22);%0A      
+  
 return webUtilsS
@@ -1481,24 +1481,26 @@
 dmin();%0A    
+ 
+ 
 %7D else if (w
@@ -1564,32 +1564,34 @@
 rDocRef%0A        
+  
 ).endsWith(%22Cele
@@ -1615,24 +1615,26 @@
 %22)) %7B%0A      
+ 
+ 
 LOGGER.debug
@@ -1708,32 +1708,34 @@
 or %5B%22%0A          
+  
 + webUtilsServic
@@ -1779,32 +1779,34 @@
 in %5B%22%0A          
+ 
+ 
 + webUtilsServic
@@ -1830,24 +1830,26 @@
 () + %22%5D.%22);%0A
+  
       return
@@ -1928,50 +1928,14 @@
     
+ 
+ 
 %7D%0A  
-  getContext().setDatabase(database);%0A
     
@@ -1980,16 +1980,80 @@
 ocRef);%0A
+    %7D finally %7B%0A      getContext().setDatabase(database);%0A    %7D%0A
   %7D%0A%0A  p

fix reset context database after hasview in DefaultMenuAccessProvider