package org.exoplatform.cs.service.util;

import java.util.List;

import org.apache.commons.lang.StringUtils;

import org.exoplatform.container.PortalContainer;
import org.exoplatform.cs.dto.SpaceDTO;
import org.exoplatform.portal.config.DataStorage;
import org.exoplatform.portal.config.model.Application;
import org.exoplatform.portal.config.model.ApplicationState;
import org.exoplatform.portal.config.model.ApplicationType;
import org.exoplatform.portal.config.model.Container;
import org.exoplatform.portal.mop.SiteType;
import org.exoplatform.portal.pom.spi.portlet.Portlet;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.social.core.space.SpaceUtils;
import org.exoplatform.social.core.space.model.Space;
import org.exoplatform.web.application.RequestContext;
import org.exoplatform.web.url.navigation.NavigationResource;
import org.exoplatform.web.url.navigation.NodeURL;

public class SpacePageUtils {
  private static final Log    LOG                          = ExoLogger.getLogger(SpacePageUtils.class);

  /**
   * The {modifiedGroupId} preference value pattern
   *
   * @since 1.2.0-GA
   */
  private static final String MODIFIED_GROUP_ID_PREFERENCE = "{modifiedGroupId}";

  public static void convert(List<?> children, String groupId) {
    if ((children == null) || (children.size() == 0)) {
      return;
    }
    for (Object child : children) {
      if (child instanceof Container) {
        Container container = (Container) child;
        convert(container.getChildren(), groupId);
      } else if (child instanceof Application && ((Application<?>) child).getType().equals(ApplicationType.PORTLET)) {
        @SuppressWarnings("unchecked")
        Application<Portlet> application = (Application<Portlet>) child;
        try {
          Portlet portlet = getPreferences(application);
          if (portlet == null) {
            continue;
          }
          //FV
          boolean modified = false;
          if (portlet.getPreference("folderPath") != null) {
            String folderPath = portlet.getPreference("folderPath").getValue();
            if (!StringUtils.isBlank(folderPath)) {
              String newFolderPath = convertPath(folderPath, groupId);
              portlet.setValue("folderPath", newFolderPath);
              modified = true;
            }
          }
          if (portlet.getPreference("nodeIdentifier") != null) {
            String nodeIdentifier = portlet.getPreference("nodeIdentifier").getValue();
            if (!StringUtils.isBlank(nodeIdentifier)) {
              String newNodeIdentifier = convertPath(nodeIdentifier, groupId);
              portlet.setValue("nodeIdentifier", newNodeIdentifier);
              modified = true;
            }
          }
          modified |= changeDriveName(groupId, portlet, "nodeDrive");
          modified |= changeDriveName(groupId, portlet, "driveName");
          if (modified) {
            savePreferences(application.getState(), portlet);
          }
        } catch (Exception e) {
          LOG.error("Can't convert CLV application preferences " + application.getId(), e);
        }
      }
    }
  }

  private static boolean changeDriveName(String groupId, Portlet portlet, String nodeDrive) {
    boolean modified = false;
    if (portlet.getPreference(nodeDrive) != null && portlet.getPreference(nodeDrive).getValue() != null
        && portlet.getPreference(nodeDrive).getValue().contains(MODIFIED_GROUP_ID_PREFERENCE)) {
      String driveName = portlet.getPreference(nodeDrive).getValue();
      String newFolderPath = driveName.replace(MODIFIED_GROUP_ID_PREFERENCE, groupId.replace("/", "."));
      portlet.setValue(nodeDrive, newFolderPath);
      modified = true;
    }
    return modified;
  }

  private static String convertPath(String originalPath, String groupId) {
    // check if the path is alive
    if (StringUtils.isEmpty(originalPath)) {
      return originalPath;
    }
    return originalPath.replaceAll("@owner@", groupId);
  }

  private static Portlet getPreferences(Application<Portlet> application) throws Exception {
    DataStorage dataStorage = (DataStorage) PortalContainer.getInstance().getComponentInstanceOfType(DataStorage.class);
    return dataStorage.load(application.getState(), application.getType());
  }

  private static void savePreferences(ApplicationState<Portlet> state, Portlet portlet) throws Exception {
    DataStorage dataStorage = (DataStorage) PortalContainer.getInstance().getComponentInstanceOfType(DataStorage.class);
    dataStorage.save(state, portlet);
  }

  public static String getSpaceHomeURL(SpaceDTO space) {
    // work-around for SOC-2366 when rename existing space
    String groupId = space.getGroupId();
    String permanentSpaceName = groupId.split("/")[2];
    String spaceName = SpaceUtils.cleanString(space.getName());
    RequestContext ctx = RequestContext.getCurrentInstance();
    NodeURL nodeURL =  ctx.createURL(NodeURL.TYPE);
    NavigationResource resource = new NavigationResource(SiteType.GROUP, SpaceUtils.SPACE_GROUP + "/"
          + permanentSpaceName, spaceName);
    return nodeURL.setResource(resource).toString();
  }
}
