package ru.systematic.cisstat.util;

import aQute.bnd.annotation.ProviderType;

import java.io.IOException;
import java.util.LinkedHashSet;
import java.util.Objects;
import java.util.Set;

import javax.portlet.PortletPreferences;
import javax.portlet.PortletRequest;

import org.osgi.service.component.annotations.Component;

import com.liferay.asset.kernel.model.AssetEntry;
import com.liferay.asset.kernel.service.AssetEntryLocalService;
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.model.Group;
import com.liferay.portal.kernel.model.GroupConstants;
import com.liferay.portal.kernel.model.Layout;
import com.liferay.portal.kernel.security.auth.PrincipalException;
import com.liferay.portal.kernel.security.auth.PrincipalThreadLocal;
import com.liferay.portal.kernel.service.GroupLocalService;
import com.liferay.portal.kernel.service.LayoutLocalService;
import com.liferay.portal.kernel.theme.ThemeDisplay;
import com.liferay.portal.kernel.util.ArrayUtil;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.WebKeys;
import com.liferay.portal.kernel.xml.Document;
import com.liferay.portal.kernel.xml.Element;
import com.liferay.portal.kernel.xml.SAXReaderUtil;
import com.liferay.sites.kernel.util.SitesUtil;

@Component(immediate = true, service = VideoNewsUtil.class)
@ProviderType
public class VideoNewsUtil {
	
	public static final String SCOPE_ID_CHILD_GROUP_PREFIX = "ChildGroup_";
	public static final String SCOPE_ID_GROUP_PREFIX = "Group_";
	public static final String SCOPE_ID_LAYOUT_PREFIX = "Layout_";
	public static final String SCOPE_ID_LAYOUT_UUID_PREFIX = "LayoutUuid_";
	public static final String SCOPE_ID_PARENT_GROUP_PREFIX = "ParentGroup_";
	
	public static long getGroupIdFromScopeId(
			String scopeId, long siteGroupId, boolean privateLayout)
		throws PortalException {

		if (scopeId.startsWith(SCOPE_ID_CHILD_GROUP_PREFIX)) {
			String scopeIdSuffix = scopeId.substring(
				SCOPE_ID_CHILD_GROUP_PREFIX.length());

			long childGroupId = GetterUtil.getLong(scopeIdSuffix);

			Group childGroup = _groupLocalService.getGroup(childGroupId);

			if (!childGroup.hasAncestor(siteGroupId)) {
				throw new PrincipalException();
			}

			return childGroupId;
		}
		else if (scopeId.startsWith(SCOPE_ID_GROUP_PREFIX)) {
			String scopeIdSuffix = scopeId.substring(
				SCOPE_ID_GROUP_PREFIX.length());

			if (scopeIdSuffix.equals(GroupConstants.DEFAULT)) {
				return siteGroupId;
			}

			long scopeGroupId = GetterUtil.getLong(scopeIdSuffix);

			Group scopeGroup = _groupLocalService.getGroup(scopeGroupId);

			return scopeGroup.getGroupId();
		}
		else if (scopeId.startsWith(SCOPE_ID_LAYOUT_UUID_PREFIX)) {
			String layoutUuid = scopeId.substring(
				SCOPE_ID_LAYOUT_UUID_PREFIX.length());

			Layout scopeIdLayout =
				_layoutLocalService.getLayoutByUuidAndGroupId(
					layoutUuid, siteGroupId, privateLayout);

			Group scopeIdGroup = _groupLocalService.checkScopeGroup(
				scopeIdLayout, PrincipalThreadLocal.getUserId());

			return scopeIdGroup.getGroupId();
		}
		else if (scopeId.startsWith(SCOPE_ID_LAYOUT_PREFIX)) {

			// Legacy portlet preferences

			String scopeIdSuffix = scopeId.substring(
				SCOPE_ID_LAYOUT_PREFIX.length());

			long scopeIdLayoutId = GetterUtil.getLong(scopeIdSuffix);

			Layout scopeIdLayout = _layoutLocalService.getLayout(
				siteGroupId, privateLayout, scopeIdLayoutId);

			Group scopeIdGroup = scopeIdLayout.getScopeGroup();

			return scopeIdGroup.getGroupId();
		}
		else if (scopeId.startsWith(SCOPE_ID_PARENT_GROUP_PREFIX)) {
			String scopeIdSuffix = scopeId.substring(
				SCOPE_ID_PARENT_GROUP_PREFIX.length());

			long parentGroupId = GetterUtil.getLong(scopeIdSuffix);

			Group parentGroup = _groupLocalService.getGroup(parentGroupId);

			if (!SitesUtil.isContentSharingWithChildrenEnabled(parentGroup)) {
				throw new PrincipalException();
			}

			Group group = _groupLocalService.getGroup(siteGroupId);

			if (!group.hasAncestor(parentGroupId)) {
				throw new PrincipalException();
			}

			return parentGroupId;
		}
		else {
			throw new IllegalArgumentException("Invalid scope ID " + scopeId);
		}
	}
	
	public static long[] getGroupIds(
			PortletPreferences portletPreferences, long scopeGroupId,
			Layout layout) {

			String[] scopeIds = portletPreferences.getValues(
				"scopeIds", new String[] {SCOPE_ID_GROUP_PREFIX + scopeGroupId});

			Set<Long> groupIds = new LinkedHashSet<>();

			for (String scopeId : scopeIds) {
				try {
					long groupId = getGroupIdFromScopeId(
						scopeId, scopeGroupId, layout.isPrivateLayout());

					groupIds.add(groupId);
				}
				catch (Exception e) {
					continue;
				}
			}

			return ArrayUtil.toLongArray(groupIds);
		}
	
	public static String[] getAssetTagNames(
			PortletPreferences portletPreferences) {

			String[] allAssetTagNames = new String[0];

			for (int i = 0; true; i++) {
				String[] queryValues = portletPreferences.getValues(
					"queryValues" + i, null);

				if (ArrayUtil.isEmpty(queryValues)) {
					break;
				}

				boolean queryContains = GetterUtil.getBoolean(
					portletPreferences.getValue(
						"queryContains" + i, StringPool.BLANK));
				boolean queryAndOperator = GetterUtil.getBoolean(
					portletPreferences.getValue(
						"queryAndOperator" + i, StringPool.BLANK));
				String queryName = portletPreferences.getValue(
					"queryName" + i, StringPool.BLANK);

				if (!Objects.equals(queryName, "assetCategories") &&
					queryContains &&
					(queryAndOperator || (queryValues.length == 1))) {

					allAssetTagNames = queryValues;
				}
			}

			return allAssetTagNames;
		}
	
	public static long[] getAssetCategoryIds(
			PortletPreferences portletPreferences) {

			long[] assetCategoryIds = new long[0];

			for (int i = 0; true; i++) {
				String[] queryValues = portletPreferences.getValues(
					"queryValues" + i, null);

				if (ArrayUtil.isEmpty(queryValues)) {
					break;
				}

				boolean queryContains = GetterUtil.getBoolean(
					portletPreferences.getValue(
						"queryContains" + i, StringPool.BLANK));
				boolean queryAndOperator = GetterUtil.getBoolean(
					portletPreferences.getValue(
						"queryAndOperator" + i, StringPool.BLANK));
				String queryName = portletPreferences.getValue(
					"queryName" + i, StringPool.BLANK);

				if (Objects.equals(queryName, "assetCategories") && queryContains &&
					(queryAndOperator || (queryValues.length == 1))) {

					assetCategoryIds = ArrayUtil.append(
						assetCategoryIds, GetterUtil.getLongValues(queryValues));
				}
			}

			return assetCategoryIds;
		}
	
	
	public static long[] getClassNameIds(
			PortletPreferences portletPreferences, long[] availableClassNameIds) {

			boolean anyAssetType = GetterUtil.getBoolean(
				portletPreferences.getValue(
					"anyAssetType", Boolean.TRUE.toString()));
			String selectionStyle = portletPreferences.getValue(
				"selectionStyle", "dynamic");

			if (anyAssetType || selectionStyle.equals("manual")) {
				return availableClassNameIds;
			}

			long defaultClassNameId = GetterUtil.getLong(
				portletPreferences.getValue("anyAssetType", null));

			if (defaultClassNameId > 0) {
				return new long[] {defaultClassNameId};
			}

			long[] classNameIds = GetterUtil.getLongValues(
				portletPreferences.getValues("classNameIds", null));

			if (ArrayUtil.isNotEmpty(classNameIds)) {
				return classNameIds;
			}
			else {
				return availableClassNameIds;
			}
		}
	
	
	public static void addSelection(
			PortletRequest portletRequest,
			PortletPreferences portletPreferences, String portletId)
		throws Exception {

		ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
			WebKeys.THEME_DISPLAY);

		long assetEntryId = ParamUtil.getLong(portletRequest, "assetEntryId");
		int assetEntryOrder = ParamUtil.getInteger(
			portletRequest, "assetEntryOrder");
		String assetEntryType = ParamUtil.getString(
			portletRequest, "assetEntryType");

		addSelection(
			themeDisplay, portletPreferences, portletId, assetEntryId,
			assetEntryOrder, assetEntryType);
	}

	public static void addSelection(
			ThemeDisplay themeDisplay, PortletPreferences portletPreferences,
			String portletId, long assetEntryId, int assetEntryOrder,
			String assetEntryType)
		throws Exception {

		AssetEntry assetEntry = _assetEntryLocalService.fetchEntry(
			assetEntryId);

		String[] assetEntryXmls = portletPreferences.getValues(
			"assetEntryXml", new String[0]);

		String assetEntryXml = _getAssetEntryXml(
			assetEntryType, assetEntry.getClassUuid());

		if (!ArrayUtil.contains(assetEntryXmls, assetEntryXml)) {
			if (assetEntryOrder > -1) {
				assetEntryXmls[assetEntryOrder] = assetEntryXml;
			}
			else {
				assetEntryXmls = ArrayUtil.append(
					assetEntryXmls, assetEntryXml);
			}

			portletPreferences.setValues("assetEntryXml", assetEntryXmls);
		}

		try {
			portletPreferences.store();
		}
		catch (IOException ioe) {
			throw new SystemException(ioe);
		}
	}
	
	private static String _getAssetEntryXml(
			String assetEntryType, String assetEntryUuid) {

			String xml = null;

			try {
				Document document = SAXReaderUtil.createDocument(StringPool.UTF8);

				Element assetEntryElement = document.addElement("asset-entry");

				Element assetEntryTypeElement = assetEntryElement.addElement(
					"asset-entry-type");

				assetEntryTypeElement.addText(assetEntryType);

				Element assetEntryUuidElement = assetEntryElement.addElement(
					"asset-entry-uuid");

				assetEntryUuidElement.addText(assetEntryUuid);

				xml = document.formattedString(StringPool.BLANK);
			}
			catch (IOException ioe) {
				if (_log.isWarnEnabled()) {
					_log.warn(ioe);
				}
			}

			return xml;
		}
	
	private static final Log _log = LogFactoryUtil.getLog(
			VideoNewsUtil.class);
	private static GroupLocalService _groupLocalService;
	private static LayoutLocalService _layoutLocalService;
	private static AssetEntryLocalService _assetEntryLocalService;
	



}
