/* (C) 2023 YiRing, Inc. */
package com.yiring.common.utils;

import com.yiring.common.core.I18n;
import com.yiring.common.core.Status;
import com.yiring.common.exception.FailStatusException;
import lombok.experimental.UtilityClass;
import org.jetbrains.annotations.PropertyKey;
import org.springframework.data.domain.Example;
import org.springframework.data.jpa.repository.JpaRepository;

/**
 * @author Jim
 * @version 0.1
 * 2023/6/25 17:43
 */

@SuppressWarnings({ "unused" })
@UtilityClass
public class RepositoryUtil {

    /**
     * 根据 ID 查询数据，如果数据不存在则抛出异常【数据未找到】
     * @param repository repository
     * @param id id
     * @return T
     * @param <T> T
     * @param <ID> ID
     * @exception FailStatusException FailStatusException
     */
    public <T, ID> T find(JpaRepository<T, ID> repository, ID id) throws FailStatusException {
        return repository.findById(id).orElseThrow(Status.NOT_FOUND::exception);
    }

    /**
     * 根据 ID 查询数据，如果数据不存在则抛出自定义异常【message】
     * @param repository repository
     * @param id id
     * @param message 自定义异常信息
     * @return T
     * @param <T> T
     * @param <ID> ID
     * @exception FailStatusException FailStatusException
     */
    public <T, ID> T find(
        JpaRepository<T, ID> repository,
        ID id,
        @PropertyKey(resourceBundle = I18n.RESOURCE_BUNDLE) String message
    ) throws FailStatusException {
        return repository.findById(id).orElseThrow(() -> Status.NOT_FOUND.exception(message));
    }

    /**
     * 根据条件查询数据，如果数据不存在则抛出异常【数据未找到】
     * @param repository repository
     * @param example example
     * @return T
     * @param <T> T
     * @param <ID> ID
     * @throws FailStatusException FailStatusException
     */
    public <T, ID> T find(JpaRepository<T, ID> repository, Example<T> example) throws FailStatusException {
        return repository.findOne(example).orElseThrow(Status.NOT_FOUND::exception);
    }

    /**
     * 根据条件查询数据，如果数据不存在则抛出自定义异常【message】
     * @param repository repository
     * @param example example
     * @param message 自定义异常信息
     * @return T
     * @param <T> T
     * @param <ID> ID
     * @throws FailStatusException FailStatusException
     */
    public <T, ID> T find(
        JpaRepository<T, ID> repository,
        Example<T> example,
        @PropertyKey(resourceBundle = I18n.RESOURCE_BUNDLE) String message
    ) throws FailStatusException {
        return repository.findOne(example).orElseThrow(() -> Status.NOT_FOUND.exception(message));
    }
}
