/*
  * (non-Javadoc)
  *
  * @see org.sakaiproject.portal.api.PortalSiteHelper#getSitesView(org.sakaiproject.portal.api.SiteView.View,
  *      javax.servlet.http.HttpServletRequest,
  *      org.sakaiproject.tool.api.Session, java.lang.String)
  */
 public SiteView getSitesView(
     View view, HttpServletRequest request, Session session, String siteId) {
   switch (view) {
     case CURRENT_SITE_VIEW:
       return new CurrentSiteViewImpl(
           this,
           portal.getSiteNeighbourhoodService(),
           request,
           session,
           siteId,
           SiteService.getInstance(),
           ServerConfigurationService.getInstance(),
           PreferencesService.getInstance());
     case ALL_SITES_VIEW:
       return new AllSitesViewImpl(
           this,
           portal.getSiteNeighbourhoodService(),
           request,
           session,
           siteId,
           SiteService.getInstance(),
           ServerConfigurationService.getInstance(),
           PreferencesService.getInstance());
     case DEFAULT_SITE_VIEW:
       return new DefaultSiteViewImpl(
           this,
           portal.getSiteNeighbourhoodService(),
           request,
           session,
           siteId,
           SiteService.getInstance(),
           ServerConfigurationService.getInstance(),
           PreferencesService.getInstance());
     case DHTML_MORE_VIEW:
       return new MoreSiteViewImpl(
           this,
           portal.getSiteNeighbourhoodService(),
           request,
           session,
           siteId,
           SiteService.getInstance(),
           ServerConfigurationService.getInstance(),
           PreferencesService.getInstance());
     case SUB_SITES_VIEW:
       return new SubSiteViewImpl(
           this,
           portal.getSiteNeighbourhoodService(),
           request,
           session,
           siteId,
           SiteService.getInstance(),
           ServerConfigurationService.getInstance(),
           PreferencesService.getInstance());
   }
   return null;
 }
  /**
   * Retrieve the list of pages in this site, checking to see if the user has permission to see the
   * page - by checking the permissions of tools on the page.
   *
   * @param site
   * @return
   */
  public List getPermittedPagesInOrder(Site site) {
    // Get all of the pages
    List pages = site.getOrderedPages();
    boolean siteUpdate = SecurityService.unlock("site.upd", site.getReference());

    List newPages = new ArrayList();

    for (Iterator i = pages.iterator(); i.hasNext(); ) {
      // check if current user has permission to see page
      SitePage p = (SitePage) i.next();
      List pTools = p.getTools();
      Iterator iPt = pTools.iterator();

      boolean allowPage = false;
      while (iPt.hasNext()) {
        ToolConfiguration placement = (ToolConfiguration) iPt.next();

        boolean thisTool = allowTool(site, placement);
        boolean unHidden = siteUpdate || !isHidden(placement);
        if (thisTool && unHidden) allowPage = true;
      }
      if (allowPage) newPages.add(p);
    }

    PageFilter pageFilter = portal.getPageFilter();

    if (pageFilter != null) {
      newPages = pageFilter.filter(newPages, site);
    }
    return newPages;
  }
  /**
   * Do the getSiteVisit, but if not found and the id is a user site, try translating from user EID
   * to ID.
   *
   * @param siteId The Site Id.
   * @return The Site.
   * @throws PermissionException If not allowed.
   * @throws IdUnusedException If not found.
   */
  public Site getSiteVisit(String siteId) throws PermissionException, IdUnusedException {
    try {
      return SiteService.getSiteVisit(siteId);
    } catch (IdUnusedException e) {
      if (SiteService.isUserSite(siteId)) {
        try {
          String userEid = SiteService.getSiteUserId(siteId);
          String userId = UserDirectoryService.getUserId(userEid);
          String alternateSiteId = SiteService.getUserSiteId(userId);
          return SiteService.getSiteVisit(alternateSiteId);
        } catch (UserNotDefinedException ee) {
        }
      } else {
        String reference = portal.getSiteNeighbourhoodService().parseSiteAlias(siteId);
        Reference ref = EntityManager.getInstance().newReference(reference);
        try {
          return SiteService.getSiteVisit(ref.getId());
        } catch (IdUnusedException iue) {
        }
      }

      // re-throw if that didn't work
      throw e;
    }
  }
  /**
   * If this is a user site, return an id based on the user EID, otherwise just return the site id.
   *
   * @param site The site.
   * @return The effective site id.
   */
  public String getSiteEffectiveId(Site site) {
    if (SiteService.isUserSite(site.getId())) {
      try {
        String userId = SiteService.getSiteUserId(site.getId());
        String eid = UserDirectoryService.getUserEid(userId);
        return SiteService.getUserSiteId(eid);
      } catch (UserNotDefinedException e) {
        log.warn("getSiteEffectiveId: user eid not found for user site: " + site.getId());
      }
    } else {
      String displayId =
          portal.getSiteNeighbourhoodService().lookupSiteAlias(site.getReference(), null);
      if (displayId != null) {
        return displayId;
      }
    }

    return site.getId();
  }
  /**
   * Produce a page and/or a tool list doPage = true is best for the tabs-based portal and for RSS -
   * these think in terms of pages doPage = false is best for the portlet-style - it unrolls all of
   * the tools unless a page is marked as a popup. If the page is a popup - it is left a page and
   * marked as such. restTools = true - generate resetting tool URLs.
   *
   * @see
   *     org.sakaiproject.portal.api.PortalSiteHelper#pageListToMap(javax.servlet.http.HttpServletRequest,
   *     boolean, org.sakaiproject.site.api.Site, org.sakaiproject.site.api.SitePage,
   *     java.lang.String, java.lang.String, boolean, boolean, boolean)
   */
  public Map pageListToMap(
      HttpServletRequest req,
      boolean loggedIn,
      Site site,
      SitePage page,
      String toolContextPath,
      String portalPrefix,
      boolean doPages,
      boolean resetTools,
      boolean includeSummary) {

    Map<String, Object> theMap = new HashMap<String, Object>();

    String pageUrl =
        Web.returnUrl(
            req, "/" + portalPrefix + "/" + Web.escapeUrl(getSiteEffectiveId(site)) + "/page/");
    String toolUrl =
        Web.returnUrl(req, "/" + portalPrefix + "/" + Web.escapeUrl(getSiteEffectiveId(site)));
    if (resetTools) {
      toolUrl = toolUrl + "/tool-reset/";
    } else {
      toolUrl = toolUrl + "/tool/";
    }

    String pagePopupUrl = Web.returnUrl(req, "/page/");
    boolean showHelp = ServerConfigurationService.getBoolean("display.help.menu", true);
    String iconUrl = "";
    try {
      if (site.getIconUrlFull() != null) iconUrl = new URI(site.getIconUrlFull()).toString();
    } catch (URISyntaxException uex) {
      log.debug("Icon URL is invalid: " + site.getIconUrlFull());
    }

    boolean published = site.isPublished();
    String type = site.getType();

    theMap.put("siteId", site.getId());
    theMap.put("pageNavPublished", Boolean.valueOf(published));
    theMap.put("pageNavType", type);
    theMap.put("pageNavIconUrl", iconUrl);
    String htmlInclude = site.getProperties().getProperty(PROP_HTML_INCLUDE);
    if (htmlInclude != null) theMap.put("siteHTMLInclude", htmlInclude);

    // theMap.put("pageNavSitToolsHead",
    // Web.escapeHtml(rb.getString("sit_toolshead")));

    // order the pages based on their tools and the tool order for the
    // site type
    // List pages = site.getOrderedPages();
    List pages = getPermittedPagesInOrder(site);

    List<Map> l = new ArrayList<Map>();

    String addMoreToolsUrl = null;
    for (Iterator i = pages.iterator(); i.hasNext(); ) {

      SitePage p = (SitePage) i.next();
      // check if current user has permission to see page
      // we will draw page button if it have permission to see at least
      // one tool on the page
      List<ToolConfiguration> pTools = p.getTools();
      ToolConfiguration firstTool = null;
      String toolsOnPage = null;

      boolean current = (page != null && p.getId().equals(page.getId()) && !p.isPopUp());
      String alias = lookupPageToAlias(site.getId(), p);
      String pagerefUrl = pageUrl + Web.escapeUrl((alias != null) ? alias : p.getId());

      if (doPages || p.isPopUp()) {
        Map<String, Object> m = new HashMap<String, Object>();
        StringBuffer desc = new StringBuffer();

        boolean hidden = false;
        if (pTools != null && pTools.size() > 0) {
          firstTool = pTools.get(0);
          hidden = true; // Only set the page to hidden when we have tools that might un-hide it.
          Iterator<ToolConfiguration> tools = pTools.iterator();
          // get the tool descriptions for this page, typically only one per page, execpt for the
          // Home page
          int tCount = 0;
          while (tools.hasNext()) {
            ToolConfiguration t = tools.next();
            if (hidden && !isHidden(t)) {
              hidden = false;
            }
            if (tCount > 0) {
              desc.append(" | ");
            }
            if (t.getTool() == null) continue;
            desc.append(t.getTool().getDescription());
            tCount++;
            if ("sakai.siteinfo".equals(t.getToolId())) {
              addMoreToolsUrl =
                  Web.returnUrl(
                      req,
                      "/site/"
                          + Web.escapeUrl(site.getId())
                          + "/page/"
                          + Web.escapeUrl(p.getId())
                          + "?sakai_action=doMenu_edit_site_tools&panel=Shortcut");
            }
          }
          // Won't work with mutliple tools per page
          if (tCount > 1) addMoreToolsUrl = null;
        }

        boolean siteUpdate = SecurityService.unlock("site.upd", site.getReference());
        if (!siteUpdate) addMoreToolsUrl = null;

        if (!ServerConfigurationService.getBoolean("portal.experimental.addmoretools", false))
          addMoreToolsUrl = null;

        m.put("isPage", Boolean.valueOf(true));
        m.put("current", Boolean.valueOf(current));
        m.put("ispopup", Boolean.valueOf(p.isPopUp()));
        m.put("pagePopupUrl", pagePopupUrl);
        m.put("pageTitle", Web.escapeHtml(p.getTitle()));
        m.put("jsPageTitle", Web.escapeJavascript(p.getTitle()));
        m.put("pageId", Web.escapeUrl(p.getId()));
        m.put("jsPageId", Web.escapeJavascript(p.getId()));
        m.put("pageRefUrl", pagerefUrl);

        // TODO: Should have Web.escapeHtmlAttribute()
        String description = desc.toString().replace("\"", "&quot;");
        m.put("description", description);
        m.put("hidden", Boolean.valueOf(hidden));
        // toolsOnPage is always null
        // if (toolsOnPage != null) m.put("toolsOnPage", toolsOnPage);
        if (includeSummary) summarizePage(m, site, p);
        if (firstTool != null) {
          String menuClass = firstTool.getToolId();
          menuClass = "icon-" + menuClass.replace('.', '-');
          m.put("menuClass", menuClass);
          Properties tmp = firstTool.getConfig();
          if (tmp != null) {
            String mc = tmp.getProperty(PROP_MENU_CLASS);
            if (mc != null && mc.length() > 0) m.put("menuClassOverride", mc);
          }
        } else {
          m.put("menuClass", "icon-default-tool");
        }
        m.put("pageProps", createPageProps(p));
        // this is here to allow the tool reorder to work
        m.put("_sitePage", p);
        l.add(m);
        continue;
      }

      // Loop through the tools again and Unroll the tools
      Iterator iPt = pTools.iterator();

      while (iPt.hasNext()) {
        ToolConfiguration placement = (ToolConfiguration) iPt.next();

        Tool tool = placement.getTool();
        if (tool != null) {
          String toolrefUrl = toolUrl + Web.escapeUrl(placement.getId());

          Map<String, Object> m = new HashMap<String, Object>();
          m.put("isPage", Boolean.valueOf(false));
          m.put("toolId", Web.escapeUrl(placement.getId()));
          m.put("jsToolId", Web.escapeJavascript(placement.getId()));
          m.put("toolRegistryId", placement.getToolId());
          m.put("toolTitle", Web.escapeHtml(placement.getTitle()));
          m.put("jsToolTitle", Web.escapeJavascript(placement.getTitle()));
          m.put("toolrefUrl", toolrefUrl);
          String menuClass = placement.getToolId();
          menuClass = "icon-" + menuClass.replace('.', '-');
          m.put("menuClass", menuClass);
          Properties tmp = placement.getConfig();
          if (tmp != null) {
            String mc = tmp.getProperty(PROP_MENU_CLASS);
            if (mc != null && mc.length() > 0) m.put("menuClassOverride", mc);
          }
          // this is here to allow the tool reorder to work if requried.
          m.put("_placement", placement);
          l.add(m);
        }
      }
    }
    PageFilter pageFilter = portal.getPageFilter();
    if (pageFilter != null) {
      l = pageFilter.filterPlacements(l, site);
    }

    if (addMoreToolsUrl != null) {
      theMap.put("pageNavAddMoreToolsUrl", addMoreToolsUrl);
      theMap.put("pageNavCanAddMoreTools", true);
    } else {
      theMap.put("pageNavCanAddMoreTools", false);
    }

    theMap.put("pageNavTools", l);
    theMap.put(
        "pageMaxIfSingle",
        ServerConfigurationService.getBoolean("portal.experimental.maximizesinglepage", false));
    theMap.put("pageNavToolsCount", Integer.valueOf(l.size()));

    String helpUrl = ServerConfigurationService.getHelpUrl(null);
    theMap.put("pageNavShowHelp", Boolean.valueOf(showHelp));
    theMap.put("pageNavHelpUrl", helpUrl);
    theMap.put("helpMenuClass", "icon-sakai-help");
    theMap.put("subsiteClass", "icon-sakai-subsite");

    // theMap.put("pageNavSitContentshead",
    // Web.escapeHtml(rb.getString("sit_contentshead")));

    // Display presence? Global property display.users.present may be always / never / true / false
    // If true or false, the value may be overriden by the site property display-users-present
    // which may be true or false.

    boolean showPresence;
    String globalShowPresence =
        ServerConfigurationService.getString("display.users.present", "true");

    if ("never".equals(globalShowPresence)) {
      showPresence = false;
    } else if ("always".equals(globalShowPresence)) {
      showPresence = true;
    } else {
      String showPresenceSite = site.getProperties().getProperty("display-users-present");

      if (showPresenceSite == null) {
        showPresence = Boolean.valueOf(globalShowPresence).booleanValue();
      } else {
        showPresence = Boolean.valueOf(showPresenceSite).booleanValue();
      }
    }

    // Check to see if this is a my workspace site, and if so, whether presence is disabled
    if (showPresence
        && SiteService.isUserSite(site.getId())
        && !ServerConfigurationService.getBoolean("display.users.present.myworkspace", false))
      showPresence = false;

    String presenceUrl = Web.returnUrl(req, "/presence/" + Web.escapeUrl(site.getId()));

    // theMap.put("pageNavSitPresenceTitle",
    // Web.escapeHtml(rb.getString("sit_presencetitle")));
    // theMap.put("pageNavSitPresenceFrameTitle",
    // Web.escapeHtml(rb.getString("sit_presenceiframetit")));
    theMap.put("pageNavShowPresenceLoggedIn", Boolean.valueOf(showPresence && loggedIn));
    theMap.put("pageNavPresenceUrl", presenceUrl);

    // Retrieve whether or not we are to put presence in a frame
    theMap.put(
        "pageNavPresenceIframe",
        Boolean.valueOf(
            ServerConfigurationService.getBoolean("display.users.present.iframe", false)));
    theMap.put(
        "sakaiPresenceTimeDelay",
        Integer.valueOf(
            ServerConfigurationService.getInt("display.users.present.time.delay", 3000)));

    return theMap;
  }