/**
 * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
 *
 * The contents of this file are subject to the terms of the Liferay Enterprise
 * Subscription 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.changeset.service.impl;

import com.liferay.changeset.exception.NoSuchEntryException;
import com.liferay.changeset.model.ChangesetCollection;
import com.liferay.changeset.model.ChangesetEntry;
import com.liferay.changeset.service.base.ChangesetEntryLocalServiceBaseImpl;
import com.liferay.portal.kernel.dao.db.DB;
import com.liferay.portal.kernel.dao.db.DBManagerUtil;
import com.liferay.portal.kernel.dao.db.DBType;
import com.liferay.portal.kernel.dao.orm.ActionableDynamicQuery;
import com.liferay.portal.kernel.dao.orm.DynamicQuery;
import com.liferay.portal.kernel.dao.orm.RestrictionsFactoryUtil;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.model.User;
import com.liferay.portal.kernel.util.ListUtil;
import com.liferay.portal.kernel.util.SetUtil;

import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

/**
 * @author Brian Wing Shun Chan
 */
public class ChangesetEntryLocalServiceImpl
	extends ChangesetEntryLocalServiceBaseImpl {

	@Override
	public ChangesetEntry addChangesetEntry(
			long userId, long changesetCollectionId, long classNameId,
			long classPK)
		throws PortalException {

		User user = userLocalService.getUser(userId);
		ChangesetCollection changesetCollection =
			changesetCollectionPersistence.fetchByPrimaryKey(
				changesetCollectionId);

		long changesetEntryId = counterLocalService.increment();

		ChangesetEntry changesetEntry = changesetEntryPersistence.create(
			changesetEntryId);

		changesetEntry.setGroupId(changesetCollection.getGroupId());
		changesetEntry.setCompanyId(user.getCompanyId());
		changesetEntry.setUserId(user.getUserId());
		changesetEntry.setUserName(user.getFullName());
		changesetEntry.setChangesetCollectionId(changesetCollectionId);
		changesetEntry.setClassNameId(classNameId);
		changesetEntry.setClassPK(classPK);

		return changesetEntryPersistence.update(changesetEntry);
	}

	@Override
	public void deleteChangesetEntries(long changesetCollectionId)
		throws PortalException {

		ActionableDynamicQuery actionableDynamicQuery =
			getActionableDynamicQuery();

		actionableDynamicQuery.setAddCriteriaMethod(
			dynamicQuery -> dynamicQuery.add(
				RestrictionsFactoryUtil.eq(
					"changesetCollectionId", changesetCollectionId)));

		actionableDynamicQuery.setPerformActionMethod(
			(ActionableDynamicQuery.PerformActionMethod<ChangesetEntry>)
				changesetEntry ->
					changesetEntryLocalService.deleteChangesetEntry(
						changesetEntry));

		actionableDynamicQuery.performActions();
	}

	@Override
	public void deleteChangesetEntries(Set<Long> changesetEntryIds)
		throws PortalException {

		if (SetUtil.isEmpty(changesetEntryIds)) {
			return;
		}

		DB db = DBManagerUtil.getDB();

		if (db.getDBType() != DBType.SQLSERVER) {
			_deleteChangesetEntries(changesetEntryIds);

			return;
		}

		List<Long> changesetEntryIdsChunk = new LinkedList<>();

		for (Long changesetEntryId : changesetEntryIds) {
			if (changesetEntryIdsChunk.size() >= 2000) {
				_deleteChangesetEntries(changesetEntryIdsChunk);

				changesetEntryIdsChunk = new LinkedList<>();
			}

			changesetEntryIdsChunk.add(changesetEntryId);
		}

		if (!ListUtil.isEmpty(changesetEntryIdsChunk)) {
			_deleteChangesetEntries(changesetEntryIdsChunk);
		}
	}

	@Override
	public void deleteEntry(long changesetId, long classNameId, long classPK) {
		ChangesetEntry changesetEntry =
			changesetEntryLocalService.fetchChangesetEntry(
				changesetId, classNameId, classPK);

		if (changesetEntry != null) {
			changesetEntryLocalService.deleteChangesetEntry(changesetEntry);
		}
	}

	@Override
	public ChangesetEntry fetchChangesetEntry(
		long changesetCollectionId, long classNameId, long classPK) {

		return changesetEntryPersistence.fetchByC_C_C(
			changesetCollectionId, classNameId, classPK);
	}

	@Override
	public ChangesetEntry fetchOrAddChangesetEntry(
			long changesetCollectionId, long classNameId, long classPK)
		throws PortalException {

		ChangesetEntry changesetEntry =
			changesetEntryLocalService.fetchChangesetEntry(
				changesetCollectionId, classNameId, classPK);

		if (changesetEntry != null) {
			return changesetEntry;
		}

		ChangesetCollection changesetCollection =
			changesetCollectionLocalService.getChangesetCollection(
				changesetCollectionId);

		User user = userLocalService.getDefaultUser(
			changesetCollection.getCompanyId());

		return changesetEntryLocalService.addChangesetEntry(
			user.getUserId(), changesetCollectionId, classNameId, classPK);
	}

	@Override
	public List<ChangesetEntry> getChangesetEntries(
		long changesetCollectionId, long classNameId) {

		return changesetEntryPersistence.findByC_C(
			changesetCollectionId, classNameId);
	}

	@Override
	public long getChangesetEntriesCount(long changesetCollectionId) {
		return changesetEntryPersistence.countByChangesetCollectionId(
			changesetCollectionId);
	}

	@Override
	public long getChangesetEntriesCount(
		long changesetCollectionId, long classNameId) {

		return changesetEntryPersistence.countByC_C(
			changesetCollectionId, classNameId);
	}

	@Override
	public long getChangesetEntriesCount(
		long changesetCollectionId, long classNameId, Set<Long> classPKs) {

		DynamicQuery dynamicQuery = dynamicQuery();

		dynamicQuery.add(
			RestrictionsFactoryUtil.eq(
				"changesetCollectionId", changesetCollectionId));
		dynamicQuery.add(
			RestrictionsFactoryUtil.eq("classNameId", classNameId));

		if (SetUtil.isNotEmpty(classPKs)) {
			dynamicQuery.add(RestrictionsFactoryUtil.in("classPK", classPKs));
		}
		else {
			return 0;
		}

		return dynamicQueryCount(dynamicQuery);
	}

	@Override
	public ChangesetEntry getChangesetEntry(
			long changesetCollectionId, long classNameId, long classPK)
		throws NoSuchEntryException {

		return changesetEntryPersistence.findByC_C_C(
			changesetCollectionId, classNameId, classPK);
	}

	private void _deleteChangesetEntries(
			Collection<Long> changesetEntryIdsChunk)
		throws PortalException {

		ActionableDynamicQuery actionableDynamicQuery =
			getActionableDynamicQuery();

		actionableDynamicQuery.setAddCriteriaMethod(
			dynamicQuery -> dynamicQuery.add(
				RestrictionsFactoryUtil.in(
					"changesetEntryId", changesetEntryIdsChunk)));

		actionableDynamicQuery.setPerformActionMethod(
			(ActionableDynamicQuery.PerformActionMethod<ChangesetEntry>)
				changesetEntry ->
					changesetEntryLocalService.deleteChangesetEntry(
						changesetEntry));

		actionableDynamicQuery.performActions();
	}

}