package eu.dnetlib.goldoa.domain;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * Created by panagiotis on 8/3/2017.
 */
@Aspect
@Component
public class HIbernateDomainConverter {
    private Log log = LogFactory.getLog(HIbernateDomainConverter.class);

    @Around("execution (java.util.List<Object> eu.dnetlib.goldoa.service.SearchManager.*(..)) ")
    public Object objectListConverter(ProceedingJoinPoint pjp) throws  Throwable{
        List obj = (List) pjp.proceed();
        ObjectMapper mapper = new ObjectMapper();

        if(obj.isEmpty())
            return obj;
        Class returnType = obj.get(0).getClass();
        String json = mapper.writeValueAsString(obj);
        return mapper.readValue(json,TypeFactory.defaultInstance().constructCollectionType(List.class,returnType));
    }

    @Around("execution (java.util.List<eu.dnetlib.goldoa.domain.*> eu.dnetlib.goldoa.service.*Manager.*(..)) ")
    public List<Object> listConverter(ProceedingJoinPoint pjp) throws Throwable {
        try {
            List obj = (List) pjp.proceed();
            ObjectMapper mapper = new ObjectMapper();
            if (obj.isEmpty())
                return obj;
            Class returnType = obj.get(0).getClass();
            String json = null;
            json = mapper.writeValueAsString(obj);
            return mapper.readValue(json, TypeFactory.defaultInstance().constructCollectionType(List.class, returnType));
        } catch (Throwable e) {
            log.debug("error ", e);
            throw e;
        }
    }

    @Around("execution (eu.dnetlib.goldoa.domain.* eu.dnetlib.goldoa.service.*Manager.*(..)) ")
    public Object objectConverter(ProceedingJoinPoint pjp) throws Throwable {

        Object obj = pjp.proceed();
        Class returnType = ((MethodSignature) pjp.getSignature()).getMethod().getReturnType();
        ObjectMapper mapper = new ObjectMapper();
        String json = mapper.writeValueAsString(returnType.cast(obj));
        return mapper.readValue(json, returnType);
    }


}
