/**
 * Copyright (c) 2000-2017 Liferay, Inc. All rights reserved.
 *
 * The contents of this file are subject to the terms of the Liferay Enterprise
 * pSubscription License ("License"). You may not use this file except in
 * compliance with the License. You can obtain a copy of the License by
 * contacting Liferay, Inc. See the License for the specific language governing
 * permissions and limitations under the License, including but not limited to
 * distribution rights of the Software.
 *
 *
 *
 */

package com.liferay.portlet.admin.util;

import com.liferay.portal.kernel.cache.CacheRegistryUtil;
import com.liferay.portal.kernel.dao.orm.ActionableDynamicQuery;
import com.liferay.portal.kernel.dao.orm.DynamicQuery;
import com.liferay.portal.kernel.dao.orm.ProjectionFactoryUtil;
import com.liferay.portal.kernel.dao.orm.Property;
import com.liferay.portal.kernel.dao.orm.PropertyFactoryUtil;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.util.PortalClassLoaderUtil;
import com.liferay.portal.kernel.util.ProxyUtil;
import com.liferay.portal.model.Layout;
import com.liferay.portal.model.LayoutRevision;
import com.liferay.portal.model.LayoutStagingHandler;
import com.liferay.portal.model.LayoutTypePortlet;
import com.liferay.portal.model.Portlet;
import com.liferay.portal.model.PortletPreferences;
import com.liferay.portal.service.LayoutLocalServiceUtil;
import com.liferay.portal.service.LayoutRevisionLocalServiceUtil;
import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
import com.liferay.portal.service.persistence.PortletPreferencesActionableDynamicQuery;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Andrew Betts
 * @author Christopher Kian
 */
public class CleanUpPortletPreferencesUtil {

	public static void cleanUpLayoutRevisionPortletPreferences()
		throws Exception {

		CacheRegistryUtil.setActive(true);

		ActionableDynamicQuery actionableDynamicQuery =
			new PortletPreferencesActionableDynamicQuery() {

			@Override
			protected void addCriteria(DynamicQuery dynamicQuery) {
				Property plidProperty = PropertyFactoryUtil.forName("plid");

				DynamicQuery layoutRevisionDynamicQuery =
					LayoutRevisionLocalServiceUtil.dynamicQuery();

				layoutRevisionDynamicQuery.setProjection(
					ProjectionFactoryUtil.property("layoutRevisionId"));

				dynamicQuery.add(plidProperty.in(layoutRevisionDynamicQuery));
			}

			@Override
			protected void performAction(Object object)
				throws PortalException, SystemException {

				PortletPreferences portletPreferences =
					(PortletPreferences)object;

				long layoutRevisionId = portletPreferences.getPlid();

				LayoutRevision layoutRevision =
					LayoutRevisionLocalServiceUtil.getLayoutRevision(
						layoutRevisionId);

				Layout layout = LayoutLocalServiceUtil.getLayout(
					layoutRevision.getPlid());

				if (!layout.isTypePortlet()) {
					return;
				}

				if (containsPortlet(
						layout, portletPreferences.getPortletId())) {

					return;
				}

				LayoutStagingHandler layoutStagingHandler =
					new LayoutStagingHandler(layout);

				layoutStagingHandler.setLayoutRevision(layoutRevision);

				Layout proxiedLayout = (Layout)ProxyUtil.newProxyInstance(
					PortalClassLoaderUtil.getClassLoader(),
					new Class[] {Layout.class}, layoutStagingHandler);

				if (containsPortlet(
						proxiedLayout, portletPreferences.getPortletId())) {

					return;
				}

				if (_log.isWarnEnabled()) {
					_log.warn(
						"Removing portlet preferences " +
							portletPreferences.getPortletPreferencesId());
				}

				PortletPreferencesLocalServiceUtil.deletePortletPreferences(
					portletPreferences);
			}

		};

		actionableDynamicQuery.performActions();

		CacheRegistryUtil.setActive(false);
	}

	protected static boolean containsPortlet(Layout layout, String portletId)
		throws PortalException, SystemException {

		LayoutTypePortlet layoutTypePortlet =
			(LayoutTypePortlet)layout.getLayoutType();

		List<Portlet> portlets = layoutTypePortlet.getAllPortlets();

		List<String> portletIds = new ArrayList<String>(portlets.size());

		for (Portlet portlet : portlets) {
			portletIds.add(Portlet.PORTLET_ID_ACCESSOR.get(portlet));
		}

		return portletIds.contains(portletId);
	}

	private static Log _log = LogFactoryUtil.getLog(
		CleanUpPortletPreferencesUtil.class);

}