/**
   * Process the blog entries
   *
   * @param httpServletRequest Request
   * @param httpServletResponse Response
   * @param blog {@link Blog} instance
   * @param context Context
   * @param entries Blog entries retrieved for the particular request
   * @return Modified set of blog entries
   * @throws org.blojsom.plugin.PluginException If there is an error processing the blog entries
   */
  public Entry[] process(
      HttpServletRequest httpServletRequest,
      HttpServletResponse httpServletResponse,
      Blog blog,
      Map context,
      Entry[] entries)
      throws PluginException {
    entries = super.process(httpServletRequest, httpServletResponse, blog, context, entries);
    String page = BlojsomUtils.getRequestValue(BlojsomConstants.PAGE_PARAM, httpServletRequest);

    String username = getUsernameFromSession(httpServletRequest, blog);
    if (!checkPermission(blog, null, username, SWITCH_THEME_PERMISSION)) {
      httpServletRequest.setAttribute(BlojsomConstants.PAGE_PARAM, ADMIN_ADMINISTRATION_PAGE);
      addOperationResultMessage(
          context,
          getAdminResource(
              FAILED_PERMISSION_KEY, FAILED_PERMISSION_KEY, blog.getBlogAdministrationLocale()));

      return entries;
    }

    if (ADMIN_LOGIN_PAGE.equals(page)) {
      return entries;
    } else {
      String action = BlojsomUtils.getRequestValue(ACTION_PARAM, httpServletRequest);

      context.put(THEME_SWITCHER_PLUGIN_AVAILABLE_THEMES, getAvailableThemes());
      context.put(THEME_SWITCHER_PLUGIN_FLAVORS, new TreeMap(blog.getTemplates()));
      context.put(THEME_SWITCHER_PLUGIN_DEFAULT_FLAVOR, blog.getBlogDefaultFlavor());
      String currentHtmlFlavor =
          (String) blog.getTemplates().get(BlojsomConstants.DEFAULT_FLAVOR_HTML);
      currentHtmlFlavor = currentHtmlFlavor.substring(0, currentHtmlFlavor.indexOf('.'));
      context.put(CURRENT_HTML_THEME, currentHtmlFlavor);

      if (SWITCH_THEME_ACTION.equals(action)) {
        String theme = BlojsomUtils.getRequestValue(THEME, httpServletRequest);
        String flavor = BlojsomUtils.getRequestValue(FLAVOR, httpServletRequest);

        if (BlojsomUtils.checkNullOrBlank(theme) || BlojsomUtils.checkNullOrBlank(flavor)) {
          addOperationResultMessage(
              context,
              getAdminResource(
                  NONE_SELECTED_KEY, NONE_SELECTED_KEY, blog.getBlogAdministrationLocale()));
          return entries;
        }

        if ("admin".equalsIgnoreCase(flavor)) {
          addOperationResultMessage(
              context,
              getAdminResource(
                  ADMIN_FLAVOR_PROTECTED_KEY,
                  ADMIN_FLAVOR_PROTECTED_KEY,
                  blog.getBlogAdministrationLocale()));
          return entries;
        }

        File copyFromTemplatesDirectory =
            new File(
                _servletConfig.getServletContext().getRealPath("/")
                    + BlojsomConstants.DEFAULT_CONFIGURATION_BASE_DIRECTORY
                    + _themesDirectory
                    + theme
                    + "/"
                    + _blojsomProperties.getProperty(BlojsomConstants.TEMPLATES_DIRECTORY_IP));

        File[] templateFiles = copyFromTemplatesDirectory.listFiles();
        String mainTemplate = null;

        if (templateFiles != null && templateFiles.length > 0) {
          for (int i = 0; i < templateFiles.length; i++) {
            File templateFile = templateFiles[i];
            if (!templateFile.isDirectory()) {
              if (templateFile.getName().startsWith(theme + ".")) {
                mainTemplate = templateFile.getName();
              }
            }
          }
        }

        File copyToTemplatesDirectory =
            new File(
                _servletConfig.getServletContext().getRealPath("/")
                    + BlojsomConstants.DEFAULT_CONFIGURATION_BASE_DIRECTORY
                    + _blojsomProperties.getProperty(BlojsomConstants.BLOGS_DIRECTORY_IP)
                    + blog.getBlogId()
                    + "/"
                    + _blojsomProperties.getProperty(BlojsomConstants.TEMPLATES_DIRECTORY_IP));

        try {
          BlojsomUtils.copyDirectory(copyFromTemplatesDirectory, copyToTemplatesDirectory);
        } catch (IOException e) {
          _logger.error(e);
          addOperationResultMessage(
              context,
              getAdminResource(
                  FAILED_THEME_TEMPLATE_COPY_KEY,
                  FAILED_THEME_TEMPLATE_COPY_KEY,
                  blog.getBlogAdministrationLocale()));
        }

        File copyFromResourcesDirectory =
            new File(
                _servletConfig.getServletContext().getRealPath("/")
                    + BlojsomConstants.DEFAULT_CONFIGURATION_BASE_DIRECTORY
                    + _themesDirectory
                    + theme
                    + "/"
                    + _blojsomProperties.getProperty(BlojsomConstants.RESOURCES_DIRECTORY_IP));
        File copyToResourcesDirectory =
            new File(
                _servletConfig.getServletContext().getRealPath("/")
                    + _blojsomProperties.getProperty(BlojsomConstants.RESOURCES_DIRECTORY_IP)
                    + blog.getBlogId()
                    + "/");

        try {
          BlojsomUtils.copyDirectory(copyFromResourcesDirectory, copyToResourcesDirectory);
        } catch (IOException e) {
          _logger.error(e);
          addOperationResultMessage(
              context,
              getAdminResource(
                  FAILED_THEME_TEMPLATE_COPY_KEY,
                  FAILED_THEME_TEMPLATE_COPY_KEY,
                  blog.getBlogAdministrationLocale()));
        }

        try {
          if (mainTemplate == null) {
            mainTemplate = (String) blog.getTemplates().get(flavor);

            _logger.debug(
                "No main template supplied for "
                    + theme
                    + " theme. Using existing template for flavor: "
                    + mainTemplate);
          } else {
            if (BlojsomConstants.DEFAULT_FLAVOR_HTML.equals(flavor)) {
              mainTemplate += ", " + "text/html;charset=UTF-8";
            }
          }

          Map templates = new HashMap(blog.getTemplates());
          templates.put(flavor, mainTemplate);
          blog.setTemplates(templates);

          _fetcher.saveBlog(blog);
        } catch (FetcherException e) {
          _logger.error(e);
          addOperationResultMessage(
              context,
              getAdminResource(
                  FAILED_FLAVOR_WRITE_KEY,
                  FAILED_FLAVOR_WRITE_KEY,
                  blog.getBlogAdministrationLocale()));

          return entries;
        }

        currentHtmlFlavor = (String) blog.getTemplates().get(BlojsomConstants.DEFAULT_FLAVOR_HTML);
        currentHtmlFlavor = currentHtmlFlavor.substring(0, currentHtmlFlavor.indexOf('.'));
        context.put(CURRENT_HTML_THEME, currentHtmlFlavor);

        addOperationResultMessage(
            context,
            formatAdminResource(
                THEME_SWITCHED_KEY,
                THEME_SWITCHED_KEY,
                blog.getBlogAdministrationLocale(),
                new Object[] {theme, flavor}));
        _eventBroadcaster.processEvent(
            new ProcessRequestEvent(
                this, new Date(), blog, httpServletRequest, httpServletResponse, context));
      } else {
        _eventBroadcaster.processEvent(
            new ProcessRequestEvent(
                this, new Date(), blog, httpServletRequest, httpServletResponse, context));

        context.put(THEME_SWITCHER_PLUGIN_AVAILABLE_THEMES, getAvailableThemes());
      }
    }

    return entries;
  }
  /**
   * Process the blog entries
   *
   * @param httpServletRequest Request
   * @param httpServletResponse Response
   * @param user {@link org.blojsom.blog.BlogUser} instance
   * @param context Context
   * @param entries Blog entries retrieved for the particular request
   * @return Modified set of blog entries
   * @throws org.blojsom.plugin.BlojsomPluginException If there is an error processing the blog
   *     entries
   */
  public BlogEntry[] process(
      HttpServletRequest httpServletRequest,
      HttpServletResponse httpServletResponse,
      BlogUser user,
      Map context,
      BlogEntry[] entries)
      throws BlojsomPluginException {
    entries = super.process(httpServletRequest, httpServletResponse, user, context, entries);
    String page = BlojsomUtils.getRequestValue(PAGE_PARAM, httpServletRequest);

    String username = getUsernameFromSession(httpServletRequest, user.getBlog());
    if (!checkPermission(user, null, username, MOBLOG_ADMIN_PERMISSION)) {
      httpServletRequest.setAttribute(PAGE_PARAM, ADMIN_LOGIN_PAGE);
      addOperationResultMessage(context, "You are not allowed to edit moblog settings");

      return entries;
    }

    if (ADMIN_LOGIN_PAGE.equals(page)) {
      return entries;
    } else {
      String action = BlojsomUtils.getRequestValue(ACTION_PARAM, httpServletRequest);
      Mailbox mailbox =
          MoblogPluginUtils.readMailboxSettingsForUser(_blojsomConfiguration, _servletConfig, user);

      if (mailbox == null) {
        mailbox = new Mailbox();
      }

      if (UPDATE_MOBLOG_SETTINGS_ACTIONS.equals(action)) {
        String moblogConfigurationFile =
            _servletConfig.getInitParameter(MoblogPlugin.PLUGIN_MOBLOG_CONFIGURATION_IP);

        boolean mailboxEnabled =
            Boolean.valueOf(BlojsomUtils.getRequestValue(MOBLOG_ENABLED, httpServletRequest))
                .booleanValue();
        mailbox.setEnabled(mailboxEnabled);
        String hostname = BlojsomUtils.getRequestValue(MOBLOG_HOSTNAME, httpServletRequest);
        mailbox.setHostName(hostname);
        String userID = BlojsomUtils.getRequestValue(MOBLOG_USERID, httpServletRequest);
        mailbox.setUserId(userID);
        String password = BlojsomUtils.getRequestValue(MOBLOG_PASSWORD, httpServletRequest);
        mailbox.setPassword(password);
        String category = BlojsomUtils.getRequestValue(MOBLOG_CATEGORY, httpServletRequest);
        category = BlojsomUtils.normalize(category);
        mailbox.setCategoryName(category);
        String textMimeTypeValue =
            BlojsomUtils.getRequestValue(MOBLOG_TEXT_MIME_TYPES, httpServletRequest);
        String[] textMimeTypes = BlojsomUtils.parseCommaList(textMimeTypeValue);
        Map textMimeMap = mailbox.getTextMimeTypes();
        for (int i = 0; i < textMimeTypes.length; i++) {
          String textMimeType = textMimeTypes[i];
          textMimeMap.put(textMimeType, textMimeType);
        }
        String attachmentMimeTypeValue =
            BlojsomUtils.getRequestValue(MOBLOG_ATTACHMENT_MIME_TYPES, httpServletRequest);
        String[] attachmentMimeTypes = BlojsomUtils.parseCommaList(attachmentMimeTypeValue);
        Map attachmentMimeMap = mailbox.getAttachmentMimeTypes();
        for (int i = 0; i < attachmentMimeTypes.length; i++) {
          String attachmentMimeType = attachmentMimeTypes[i];
          attachmentMimeMap.put(attachmentMimeType, attachmentMimeType);
        }
        String imageMimeTypeValue =
            BlojsomUtils.getRequestValue(MOBLOG_IMAGE_MIME_TYPES, httpServletRequest);
        String[] imageMimeTypes = BlojsomUtils.parseCommaList(imageMimeTypeValue);
        Map imageMimeMap = mailbox.getImageMimeTypes();
        for (int i = 0; i < imageMimeTypes.length; i++) {
          String imageMimeType = imageMimeTypes[i];
          imageMimeMap.put(imageMimeType, imageMimeType);
        }
        String secretWord = BlojsomUtils.getRequestValue(MOBLOG_SECRET_WORD, httpServletRequest);
        mailbox.setSecretWord(secretWord);
        String ignoreExpression =
            BlojsomUtils.getRequestValue(MOBLOG_IGNORE_EXPRESSION, httpServletRequest);
        mailbox.setIgnoreExpression(ignoreExpression);

        try {
          writeMoblogConfiguration(user.getId(), moblogConfigurationFile, mailbox);
          addOperationResultMessage(context, "Updated moblog configuration");
        } catch (IOException e) {
          _logger.error(e);
          addOperationResultMessage(context, "Unable to write moblog configuration");
        }
      } else if (ADD_AUTHORIZED_ADDRESS_ACTION.equals(action)) {
        String addressToAdd =
            BlojsomUtils.getRequestValue(MOBLOG_AUTHORIZED_ADDRESS, httpServletRequest);
        if (!BlojsomUtils.checkNullOrBlank(addressToAdd)) {
          Map authorizedEmailAddresses = mailbox.getAuthorizedAddresses();
          authorizedEmailAddresses.put(addressToAdd, addressToAdd);

          try {
            writeAuthorizedEmailAddresssConfiguration(
                user.getId(),
                MoblogPlugin.DEFAULT_MOBLOG_AUTHORIZATION_FILE,
                authorizedEmailAddresses);
            addOperationResultMessage(
                context, "Added e-mail address to moblog authorized addresses: " + addressToAdd);
          } catch (IOException e) {
            _logger.error(e);
            addOperationResultMessage(context, "Unable to add e-mail address");
          }
        } else {
          addOperationResultMessage(context, "No e-mail address to add");
        }
      } else if (DELETE_AUTHORIZED_ADDRESS_ACTION.equals(action)) {
        String addressToDelete =
            BlojsomUtils.getRequestValue(MOBLOG_AUTHORIZED_ADDRESS, httpServletRequest);
        if (!BlojsomUtils.checkNullOrBlank(addressToDelete)) {
          Map authorizedEmailAddresses = mailbox.getAuthorizedAddresses();
          authorizedEmailAddresses.remove(addressToDelete);

          try {
            writeAuthorizedEmailAddresssConfiguration(
                user.getId(),
                MoblogPlugin.DEFAULT_MOBLOG_AUTHORIZATION_FILE,
                authorizedEmailAddresses);
            addOperationResultMessage(
                context,
                "Removed e-mail address from moblog authorized addresses: " + addressToDelete);
          } catch (IOException e) {
            _logger.error(e);
            addOperationResultMessage(context, "Unable to delete e-mail address");
          }
        } else {
          addOperationResultMessage(context, "No e-mail address to delete");
        }
      }

      context.put(BLOJSOM_PLUGIN_MOBLOG_MAILBOX, mailbox);
    }

    return entries;
  }
  /**
   * Process the blog entries
   *
   * @param httpServletRequest Request
   * @param httpServletResponse Response
   * @param blog {@link Blog} instance
   * @param context Context
   * @param entries Blog entries retrieved for the particular request
   * @return Modified set of blog entries
   * @throws PluginException If there is an error processing the blog entries
   */
  public Entry[] process(
      HttpServletRequest httpServletRequest,
      HttpServletResponse httpServletResponse,
      Blog blog,
      Map context,
      Entry[] entries)
      throws PluginException {
    entries = super.process(httpServletRequest, httpServletResponse, blog, context, entries);

    String page = BlojsomUtils.getRequestValue(BlojsomConstants.PAGE_PARAM, httpServletRequest);

    String username = getUsernameFromSession(httpServletRequest, blog);
    if (!checkPermission(blog, null, username, IP_MODERATION_PERMISSION)) {
      httpServletRequest.setAttribute(BlojsomConstants.PAGE_PARAM, ADMIN_ADMINISTRATION_PAGE);
      addOperationResultMessage(
          context,
          getAdminResource(
              FAILED_IP_ADDRESS_MODERATION_PERMISSION_KEY,
              FAILED_IP_ADDRESS_MODERATION_PERMISSION_KEY,
              blog.getBlogAdministrationLocale()));

      return entries;
    }

    if (ADMIN_LOGIN_PAGE.equals(page)) {
      return entries;
    } else {
      String action = BlojsomUtils.getRequestValue(ACTION_PARAM, httpServletRequest);
      List ipAddressesFromBlacklist = loadIPList(blog, IP_BLACKLIST_IP);
      List ipAddressesFromWhitelist = loadIPList(blog, IP_WHITELIST_IP);
      String listType = BlojsomUtils.getRequestValue(LIST_TYPE, httpServletRequest);

      if (ADD_IP_ADDRESS_ACTION.equals(action)) {
        String ipAddress = BlojsomUtils.getRequestValue(IP_ADDRESS, httpServletRequest);

        if (BLACKLIST.equals(listType)) {
          if (!ipAddressesFromBlacklist.contains(ipAddress)) {
            ipAddressesFromBlacklist.add(ipAddress);
            blog.setProperty(
                IP_BLACKLIST_IP, BlojsomUtils.listToString(ipAddressesFromBlacklist, "\n"));
            try {
              _fetcher.saveBlog(blog);
            } catch (FetcherException e) {
              if (_logger.isErrorEnabled()) {
                _logger.error(e);
              }
            }
            addOperationResultMessage(
                context,
                formatAdminResource(
                    ADDED_IP_TO_BLACKLIST_KEY,
                    ADDED_IP_TO_BLACKLIST_KEY,
                    blog.getBlogAdministrationLocale(),
                    new Object[] {ipAddress}));
          } else {
            addOperationResultMessage(
                context,
                formatAdminResource(
                    IP_ALREADY_ADDED_TO_BLACKLIST_KEY,
                    IP_ALREADY_ADDED_TO_BLACKLIST_KEY,
                    blog.getBlogAdministrationLocale(),
                    new Object[] {ipAddress}));
          }
        } else {
          if (!ipAddressesFromWhitelist.contains(ipAddress)) {
            ipAddressesFromWhitelist.add(ipAddress);
            blog.setProperty(
                IP_WHITELIST_IP, BlojsomUtils.listToString(ipAddressesFromWhitelist, "\n"));
            try {
              _fetcher.saveBlog(blog);
            } catch (FetcherException e) {
              if (_logger.isErrorEnabled()) {
                _logger.error(e);
              }
            }
            addOperationResultMessage(
                context,
                formatAdminResource(
                    ADDED_IP_TO_WHITELIST_KEY,
                    ADDED_IP_TO_WHITELIST_KEY,
                    blog.getBlogAdministrationLocale(),
                    new Object[] {ipAddress}));
          } else {
            addOperationResultMessage(
                context,
                formatAdminResource(
                    IP_ALREADY_ADDED_TO_WHITELIST_KEY,
                    IP_ALREADY_ADDED_TO_WHITELIST_KEY,
                    blog.getBlogAdministrationLocale(),
                    new Object[] {ipAddress}));
          }
        }
      } else if (DELETE_IP_ADDRESS_ACTION.equals(action)) {
        String[] ipAddressesToDelete = httpServletRequest.getParameterValues(IP_ADDRESS);

        if (ipAddressesToDelete != null && ipAddressesToDelete.length > 0) {
          if (BLACKLIST.equals(listType)) {
            for (int i = 0; i < ipAddressesToDelete.length; i++) {
              ipAddressesFromBlacklist.set(Integer.parseInt(ipAddressesToDelete[i]), null);
            }

            ipAddressesFromBlacklist = BlojsomUtils.removeNullValues(ipAddressesFromBlacklist);
            blog.setProperty(
                IP_BLACKLIST_IP, BlojsomUtils.listToString(ipAddressesFromBlacklist, "\n"));
            try {
              _fetcher.saveBlog(blog);
            } catch (FetcherException e) {
              if (_logger.isErrorEnabled()) {
                _logger.error(e);
              }
            }
            addOperationResultMessage(
                context,
                formatAdminResource(
                    DELETED_IP_ADDRESSES_BLACKLIST_KEY,
                    DELETED_IP_ADDRESSES_BLACKLIST_KEY,
                    blog.getBlogAdministrationLocale(),
                    new Object[] {new Integer(ipAddressesToDelete.length)}));
          } else {
            for (int i = 0; i < ipAddressesToDelete.length; i++) {
              ipAddressesFromWhitelist.set(Integer.parseInt(ipAddressesToDelete[i]), null);
            }

            ipAddressesFromWhitelist = BlojsomUtils.removeNullValues(ipAddressesFromWhitelist);
            blog.setProperty(
                IP_WHITELIST_IP, BlojsomUtils.listToString(ipAddressesFromWhitelist, "\n"));
            try {
              _fetcher.saveBlog(blog);
            } catch (FetcherException e) {
              if (_logger.isErrorEnabled()) {
                _logger.error(e);
              }
            }
            addOperationResultMessage(
                context,
                formatAdminResource(
                    DELETED_IP_ADDRESSES_WHITELIST_KEY,
                    DELETED_IP_ADDRESSES_WHITELIST_KEY,
                    blog.getBlogAdministrationLocale(),
                    new Object[] {new Integer(ipAddressesToDelete.length)}));
          }
        } else {
          addOperationResultMessage(
              context,
              getAdminResource(
                  NO_IP_ADDRESSES_SELECTED_KEY,
                  NO_IP_ADDRESSES_SELECTED_KEY,
                  blog.getBlogAdministrationLocale()));
        }
      }

      context.put(BLOJSOM_PLUGIN_IP_BLACKLIST, ipAddressesFromBlacklist);
      context.put(BLOJSOM_PLUGIN_IP_WHITELIST, ipAddressesFromWhitelist);
    }

    return entries;
  }